Jump to page: 1 2
Thread overview
struggling to link against a C global in D (win/vs2017)
Oct 29, 2018
DanielG
Oct 29, 2018
Adam D. Ruppe
Oct 29, 2018
DanielG
Oct 29, 2018
Adam D. Ruppe
Oct 29, 2018
Stanislav Blinov
Oct 29, 2018
DanielG
Oct 29, 2018
12345swordy
Oct 29, 2018
kinke
Oct 29, 2018
kinke
Oct 29, 2018
kinke
Oct 29, 2018
DanielG
October 29, 2018
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)?
October 29, 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.
October 29, 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).

October 29, 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).

October 29, 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)

October 29, 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.
October 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.
October 29, 2018
On Monday, 29 October 2018 at 00:52:32 UTC, kinke wrote:
> The names it spits out are undecorated

Correction: they *are* the decorated ones, i.e., the real final names.
October 29, 2018
On Monday, 29 October 2018 at 00:01:21 UTC, DanielG wrote:
> DLLPROJECT_API

I 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.
October 29, 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.

« First   ‹ Prev
1 2