Unknown (?) Feature - EXPORT attribute instead of EXP file

This feature is supported in the Clarion compiler since C6.0 but I’m not sure it has been documented ever.

Static variables and structures can have the EXPORT attribute. If a data object has the EXPORT attribute, it is automatically adding to the DLL’s export list. All additional components for structures with the EXPORT attribute are exporting too, for example, TCB and the type string are exporting for a QUEUE besides its buffer.

The EXPORT attribute is available for functions implemented in the DLL’s sources and declared in the global or one of module’s MAP structures. The EXPORT attribute for functions can have one string parameter - the export name for that function.
Clarion.Export.zip (507 Bytes)

3 Likes

I’m on my phone so cannot see your attachment. I think what you refer to was covered in the 7.1 ReadMe. I covered a little at CIDC in “Features you may have missed”. I’ve used it a little bit I’ve never seen anyone use it. Most like having an EXP file.

FEATURE: New attribute for procedure prototypes and static variables declarations: EXPORT. The EXPORT attribute forces the variable or procedure to be added to the export list of the DLL even if it is not listed in the EXPORTS section of the EXP file.

Also interesting is the ability to rename:

FEATURE: Ability to use substitution of exported name in the EXPORTS section of the EXP file. The entry in the EXPORTS section can have format [=] @?

I think the Microsoft Linker has these features and they are documented more. See __declspec(dllexport) and .Def EXPORTS

The Microsoft syntax for an export definition is:

entryname[=internal_name|other_module.exported_name] [@ordinal [NONAME] ] [ [PRIVATE] | [DATA]

IIRC one way way to make an EXP is to add EXPORT to Class / Procedure then build. Open the Lib or DLL in LibMaker and there are all your mangled / decorated names. You can copy them into the EXP and remove EXPORT. … For those that want everything in an EXP.

Is there a way, within a module to force LARGE_ADDRESS when compiled as an EXE, vs using an EXP?

Some linker commands can be set using the link_option pragma. But the command to set the IMAGE_FLAG_LARGE_ADDRESS_AWARE flag is among those that can be specified in one of two ways:

  • as /LARGE_ADDRESS option in the LNK file
  • as LARGE_ADDRESS directive in the EXP file.

The EXP file can be used to link EXE files - just do not use the EXPORTS section in it,

Thanks. Yeah, I’ve been using exp.

Hi @also

What would be the correct way to utilize EXPORT on classes and class methods?

Would it also handle the VMT$ and TYPE$ export definitions that we usually put in the .EXP?

Thank you

Just use it.

Yes. The EXPORT attribute on a CLASS/CLASS instance declaration forces to be exported:

  • the class object (if declaration has no the TYPE attribute)
  • the class type string (TYPE$…)
  • the class VMT (VMT$…)
  • all virtual and non-virtual methods including methods declared with the PRIVATE or PROTECTED attribute
1 Like

The compiler must report an error if the EXPORT attribute is using together with the EXTERNAL attribute. At the moment I would add the possibility to use EXPORT for variables/functions declared with the DLL(1) attribute with optional providing another external name.

1 Like

Thank you very much.

I’m also a little fuzzy how that might work with the LINK() and DLL() switches in an .INC file.

For example, if using _ABCLinkMode_=>0 and _ABCDllMode_=>1 define settings on the project, will my EXPORT switches still force an export from this DLL, even though the actual compiled code is in another DLL?

If that’s the case, then the only way I can think of to remedy that would be OMIT/COMPILE of different declarations of the same class. Or am I underthinking this?

1 Like

The EXPORT attribute causes the putting specific COMENT records to the OBJ file. The linker handles them on building the target file. If target file is EXE, these records are just ignoring by the linker. If the target file is LIB, these records are being processed by the linker on processing this LIB in other projects. So, the EXPORT attribute has no any impact to the DLL attribute.

The goal of the LINK attribute is to avoid explicit adding files with the CLASS code to the project. Again the compiler adds specific COMENT records to the OBJ file. These records are processing by the Project System. Ditto for the CLASS’s MODULE attribute. So, the EXPORT and LINK attributes have no any relation.

I’m not clear on your answer.
Will the below single line of code work:
To Not Export the Class made External when _Link_=>0 and _DLL_=>1 ?
But Will Export the Class when _Link_=>1 and _DLL_=>0 ?

MyClass CLASS,TYPE,MODULE('My'),LINK('My',_Link_),DLL(_Dll_), EXPORT

Or must OMIT/COMPILE be used like below? So when class is External (DLL(1)) the “Export” does appear ?

   COMPILE('** Internal **',_Link_)   !Compiles when _Link_=>1
MyClass CLASS,TYPE,MODULE('My'),LINK('My',_Link_),DLL(_Dll_), EXPORT
   ** Internal **

   COMPILE('** External **',_Dll_)   !Compiles when _Dll_=>1
MyClass CLASS,TYPE,MODULE('My'),LINK('My',_Link_),DLL(_Dll_)   ! No => EXPORT
   ** External **

I think you said that it would be nice to allow _Symbol_ as in EXPORT( _Symbol_ )

A related Linker question… Adding DYNAMIC_BASE or DEP to the EXP turns those ON. Is there a way in the EXP to turn them OFF e.g. DYNAMIC_BASE = False. The reason I ask is the CwProj defaults to turning those ON. AFAIK a Template cannot change those in the CwProj to be Off.

Unless I am misunderstanding your explanation, it doesn’t look to me anything is being ignored in the EXE project. I’m getting a “duplicate export name”. So this would indicate to me that we’d have to use the OMIT/COMPILE construct as Carl posted. And I’m not sure I can see how this is advantageous to adding to the .EXP manually (for Classes :slight_smile: ).

1 Like

If there was a param we could pass to EXPORT, like we do for DLL, that would be cool .EXPORT(_ABCLinkMode_)

IMO it helps a lot doing a LOT of mangling for you, at the cost of duplicate Class lines plus Compile() decoration. Image how unpleasant it would be on the Import side to have to create an .IMP file with all the mangled imports.

I’m working on converting 27 Classes from C5 with an EXP of 3500 lines. Once it no longer needs C5 will probably change to use EXPORT attribute and drop the EXP.

Yes, I was inaccurate. The DLL attribute mainly has value when the CLASS declaration is using outside the module where it is implemented. The parameter of the DLL attribute was introduced just to reduce number of conditional compilation and avoid nested OMIT/COMPILE blocks. The scanner with support of nested OMITs/COMPILEs was announced but accidentally was rolled back. This feature will be supported in the C12 compiler.

Therefore EXPORT is not compatible with the DLL(1) attribute.

More exactly:

   COMPILE('** Internal **',_Link_)   !Compiles when _Link_=>1
MyClass CLASS,TYPE,MODULE('My'),LINK('My',_Link_),EXPORT
   ** Internal **

No, I said about re-export of symbols imported from other DLLs.

1 Like

I can dig what you’re saying, but I think I’ll sit on the fence for a while.

A lot of the mangling is done for you with Unresolved External errors.

I like your idea, but the thought of managing 27 * 2 sets of class defs could get unwieldly, especially if you have more than one person working in that code.

And, since it’s unconventional, nobody new will have any idea why you did that unless you have really good comments in every include. :slight_smile:

Neither way is great.

The Project System uses default values for DYNAMIC_BASE and DEP settings to add /DYNAMIC_BASE and /DEP options to the LNK file. I’m practically do no use the IDE. I guess that the Project Properties dialog must have controls to set/clear these settings. To disable them in the old style PRJ project files it’s need to add link_option pragmas:
#pragma link_option(dynamic_base=>off)
#pragma link_option(dep=>off)

I need some time to try to find how to disable these settings in CWPROJ files.

1 Like

I made a tool to take error lines: Unresolved External Name@FMangling in somefile.obj
And turn it into proper EXP lines: Name@FMangling @?

It also tries to sort the by Class. I had a lot of these to get right.

Ahhh … I would call that Job Security ?

But seriously … “EXPORT” would be on the one line and " !No Export " on the other.