digitalmars.D.learn - struggling to link against a C global in D (win/vs2017)
- DanielG (26/26) Oct 28 2018 So I have a DLL+LIB exporting this:
- Adam D. Ruppe (3/5) Oct 28 2018 Both are listed as extern, where is the actual variable stored?
- DanielG (7/9) Oct 28 2018 It's defined in the .cpp file. This is how the built-in DLL
- Adam D. Ruppe (6/7) Oct 28 2018 Ah, of course, good.
- Stanislav Blinov (3/9) Oct 28 2018 Should it be extern(Windows), perchance?.. (I haven't D on
- DanielG (7/9) Oct 28 2018 The stdcall calling convention? I think that would only matter
- 12345swordy (3/14) Oct 29 2018 Nope, you use export.
- kinke (10/11) Oct 28 2018 I'd examine the dumpbin output of your (native) import library,
- kinke (3/4) Oct 28 2018 Correction: they *are* the decorated ones, i.e., the real final
- kinke (5/6) Oct 28 2018 I guess that's a __declspec(dllexport); in that case try
- DanielG (2/3) Oct 28 2018 Bingo!! That did the trick. Thank you so much.
So I have a DLL+LIB exporting this: extern "C" { extern DLLPROJECT_API int myIntValue; DLLPROJECT_API int myIntFunc(int a, int b); } In my D app I'm declaring it this way: extern (C) { extern __gshared int myIntValue; int myIntFunc (int a, int b); } The function seems to link OK, but the C global will not. Combinations I've tried: - dmd 32-bit, linked against a coffimplib'ed lib file. This links both successfully BUT myIntValue is trashed. myIntFunc does work properly however. - dmd m32mscoff, linking against native VS2017 lib. Complains about variable but not the function. - dmd m64, linking against native VS2017 lib. Complains about the variable but not the function. - ldc2 64-bit, linking against native VS2017 lib. Complains about the variable but not the function. I've examined the .DLL directly and the exported name "myIntValue" looks exactly like what dmd/ldc2 are complaining they cannot find. What's the magic recipe here to get this variable linked (and not gibberish)?
Oct 28 2018
On Monday, 29 October 2018 at 00:01:21 UTC, DanielG wrote:extern DLLPROJECT_API int myIntValue; extern __gshared int myIntValue;Both are listed as extern, where is the actual variable stored? If it is in the dll, it shouldn't be extern there.
Oct 28 2018
On Monday, 29 October 2018 at 00:04:54 UTC, Adam D. Ruppe wrote:Both are listed as extern, where is the actual variable stored? If it is in the dll, it shouldn't be extern there.It's defined in the .cpp file. This is how the built-in DLL template generates it - "extern" in the .h file, actual definition in the .cpp file. If you don't have "extern" there, anybody who #includes that .h file would inadvertently have the variable defined, which would result in duplicates (and won't compile).
Oct 28 2018
On Monday, 29 October 2018 at 00:12:43 UTC, DanielG wrote:It's defined in the .cpp file.Ah, of course, good. The other thing that might be an issue is the leading _ the compiler frequently adds. You might be able to hack it with pragma(mangle, "myIntValue") on the declaration too. idk for sure tho.
Oct 28 2018
On Monday, 29 October 2018 at 00:01:21 UTC, DanielG wrote:In my D app I'm declaring it this way: extern (C) { extern __gshared int myIntValue; int myIntFunc (int a, int b); } The function seems to link OK, but the C global will not.Should it be extern(Windows), perchance?.. (I haven't D on Windows for ages).
Oct 28 2018
On Monday, 29 October 2018 at 00:16:38 UTC, Stanislav Blinov wrote:Should it be extern(Windows), perchance?.. (I haven't D on Windows for ages).The stdcall calling convention? I think that would only matter for the function, and indeed, trying that breaks the function being able to link** (and the variable remains broken) ** in 32-bit mscoff mode - no effect on 64-bit (where I think stdcall isn't applicable)
Oct 28 2018
On Monday, 29 October 2018 at 00:16:38 UTC, Stanislav Blinov wrote:On Monday, 29 October 2018 at 00:01:21 UTC, DanielG wrote:Nope, you use export.In my D app I'm declaring it this way: extern (C) { extern __gshared int myIntValue; int myIntFunc (int a, int b); } The function seems to link OK, but the C global will not.Should it be extern(Windows), perchance?.. (I haven't D on Windows for ages).
Oct 29 2018
On Monday, 29 October 2018 at 00:01:21 UTC, DanielG wrote:[...]I'd examine the dumpbin output of your (native) import library, e.g., `dumpbin /symbols blub.lib`. You can also list exports etc. The names it spits out are undecorated, i.e., C symbols for Win32 libs will feature the implicit _ prefix. A C global in D on Win32 will always get the _ prefix, incl. names overridden via pragma(mangle, 'name') (=> _name). You can cheat by declaring it as `extern(C++)`, where there's no _ prefix. On Win64, there shouldn't be any name decoration for C symbols though.
Oct 28 2018
On Monday, 29 October 2018 at 00:52:32 UTC, kinke wrote:The names it spits out are undecoratedCorrection: they *are* the decorated ones, i.e., the real final names.
Oct 28 2018
On Monday, 29 October 2018 at 00:01:21 UTC, DanielG wrote:DLLPROJECT_APII guess that's a __declspec(dllexport); in that case try export extern(C) extern __gshared int myIntValue; => that's dllimport for extern variables, and dllexport for non-extern ones.
Oct 28 2018
On Monday, 29 October 2018 at 01:03:32 UTC, kinke wrote:export extern(C) extern __gshared int myIntValue;Bingo!! That did the trick. Thank you so much.
Oct 28 2018