digitalmars.D - Making a forward declaration of a C symbol defined in another CU
- Alexander Nicholi (33/33) Dec 20 2018 I'm developing for Windows, 64-bit at the moment with MSVC and
- Dennis (3/8) Dec 20 2018 Mark these as external, so extern(C) extern const ...
- Alexander Nicholi (4/13) Dec 20 2018 Oh, that works fine, thanks. I thought I already did that with
- Dennis (4/7) Dec 20 2018 Indeed, extern(C) only changes the mangled name and calling
- Joakim (8/11) Dec 20 2018 This belongs in the Learn forum:
I'm developing for Windows, 64-bit at the moment with MSVC and DMD. I have this C code file, config.c: #define STRINGIZE( x ) STRINGIZE_( x ) #define STRINGIZE_( x ) #x const xu16 ocoCoreVerMajor = _MILES_VER_MAJOR; const xu16 ocoCoreVerMinor = _MILES_VER_MINOR; const xu16 ocoCoreVerPatch = _MILES_VER_PATCH; const char* ocoCoreVerBuild = STRINGIZE( _MILES_VER_BUILD ); const char* ocoCoreTimestamp = STRINGIZE( _MILES_BUILD_TSTAMP ); And for D code, I have this interface, config.d: module oco.core.config; extern (C) const ushort ocoCoreVerMajor; extern (C) const ushort ocoCoreVerMinor; extern (C) const ushort ocoCoreVerPatch; extern (C) const char* ocoCoreVerBuild; extern (C) const char* ocoCoreTimestamp; The linker gives me this error: [ÔÇô/debug] Linking oco... [ÔÇô/debug stop] config.d.obj : error LNK2005: ocoCoreVerMajor already defined in config.c.obj ... [ÔÇô/debug stop] C:\Users\Alex\AppData\Local\Temp\miles-build\oco.exe : fatal error LNK1169: one or more multiply defined symbols found [ÔÇô/debug stop] I figure the D code is defining symbols redundantly, and they're not weakly defined, so this happens. Obviously I can't exactly just hand the definitions into D, as you can see by the C code this is actually the best way to pass these values around across language boundaries (there are a few). How do I tell D to treat this right?
Dec 20 2018
On Thursday, 20 December 2018 at 08:17:58 UTC, Alexander Nicholi wrote:extern (C) const ushort ocoCoreVerMajor; extern (C) const ushort ocoCoreVerMinor; extern (C) const ushort ocoCoreVerPatch; extern (C) const char* ocoCoreVerBuild; extern (C) const char* ocoCoreTimestamp;Mark these as external, so extern(C) extern const ...
Dec 20 2018
On Thursday, 20 December 2018 at 08:27:55 UTC, Dennis wrote:On Thursday, 20 December 2018 at 08:17:58 UTC, Alexander Nicholi wrote:Oh, that works fine, thanks. I thought I already did that with the extern (C), but I guess that's a different kind of extern isn't itextern (C) const ushort ocoCoreVerMajor; extern (C) const ushort ocoCoreVerMinor; extern (C) const ushort ocoCoreVerPatch; extern (C) const char* ocoCoreVerBuild; extern (C) const char* ocoCoreTimestamp;Mark these as external, so extern(C) extern const ...
Dec 20 2018
On Thursday, 20 December 2018 at 08:31:53 UTC, Alexander Nicholi wrote:Oh, that works fine, thanks. I thought I already did that with the extern (C), but I guess that's a different kind of extern isn't itIndeed, extern(C) only changes the mangled name and calling convention, it doesn't also mark variables as extern.
Dec 20 2018
On Thursday, 20 December 2018 at 08:17:58 UTC, Alexander Nicholi wrote:I'm developing for Windows, 64-bit at the moment with MSVC and DMD. I have this C code file, config.c: [...]This belongs in the Learn forum: https://forum.dlang.org/group/learn See the docs on interfacing to C globals, you need the additional `extern` storage class: https://dlang.org/spec/interfaceToC.html#c-globals https://dlang.org/spec/declaration.html#extern
Dec 20 2018