export keyword messes up static linking

torhu fake at address.dude
Fri Jan 26 10:43:37 PST 2007


Frits van Bommel wrote:
> torhu wrote:
>> I think I'll try to restate the problem in a simpler way.
>> 
>> I have a C lib, that I want to link with D apps.  So I write a D 
>> 'header', like so:
>> 
>> module clib;
>> 
>> export extern extern (C) {
>>     int foo;
>>     char* bar;
>> }
>> 
>> 
>> This works just fine, if I link dynamically with the C lib.  But if I 
>> want to link statically, it doesn't work.  This is because 'export' 
>> can't be there when you link statically.  foo and bar ptr get random 
>> values in the D app.
>> 
>> In this example 'export' works like msvc's __declspec(dllimport).  So in 
>> C code, you could use a macro to turn it off for static linking.
>> 
>> 
>> Does Optlink have a switch for this, or can someone tell me how to write 
>> a .def file so I don't have to declare the variables 'export'?
>> 
>> This C lib is cross-platform, so I'd also like to know if gcc (for dmd 
>> use), or at least gdc has a solution for this.  Currently we use a 
>> script that just does 's/export//g'.
> 
> Put "version(C_Lib_Dll) export:" before your declarations.
> If you then pass "-version=C_Lib_Dll" (no quotes) to DMD (or something 
> like "-fversion=C_Lib_Dll" to GDC) when compiling, or put "version = 
> C_Lib_Dll" in the source above that line, 'export' will be applied to 
> all declarations after that. If you don't do any of those things, it 
> won't. This means you have to put all non-exported symbols (if any) 
> above this line, though.
> Of course, the "C_Lib_Dll" should be changed to something unique to your 
> C library (and preferably indicate it is to be loaded as a DLL).
> Normally, the scope of such a statement can be limited by putting it in 
> a {} block, but those aren't allowed at module scope.

Part of the problem is that I want to keep the .d files as close the .h 
files as possible, so it's easier to find where things are when updating 
them for new versions etc.

from http://www.digitalmars.com/d/attribute.html :
"Export means that any code outside the executable can access the 
member. Export is analogous to exporting definitions from a DLL."

This is all that's written about export, apart from some examples on the 
pages about DLL's and '.h to .d'.  They mostly show  that export is also 
used for importing definitions from a DLL, not just exporting.

Just putting this on top of the file seems to work with dmd on windows, 
at least after some preliminary testing:

version (STATICLINK) {}
else export:

I didn't think of using export with a colon, but it seems the best 
alternative to search and replace.  Can I safely assume that if I have a 
definition in the D code that is declared export (but not extern), it 
will still be a definition?  That seems to be the idea, but I don't feel 
entirely safe.

The other way, leaving out 'export' for symbols that are imported from 
the DLL when doing dynamic linking actually works for some symbols but 
not others, which is a bit scary.  It's not needed for functions, just 
for variables.


More information about the Digitalmars-d-learn mailing list