C.h to D conversion (structs)

Adam D. Ruppe via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Mar 15 11:47:22 PDT 2016


On Tuesday, 15 March 2016 at 18:04:00 UTC, Chris wrote:
> I'm not 100% sure what you mean with compile+link in the 
> modules.

Like you would another D library.

> The structs are all defined in the original (third party) C 
> header file. It's nothing I added (in which case I would have 
> to recompile the C library). The C structs in the C library 
> should be visible to the linker, shouldn't they?

The problem isn't the struct itself, but the D initializer. 
Structs in C don't have initalizers but do in D:

struct Foo {
    int a = 10; /* illegal in C, legal in D */
};


Note that extern(C) doesn't actually do anything on a struct, it 
really only applies to functions and global variables.


D realizes this by creating a variable called _DStructName__init 
which has the initial value of the struct. When you make a 
variable of that type, it copies the value of this hidden init 
thing over to your new variable to initialize it. C does nothing 
of the sort, so the C library will not provide this - you need to 
link in the one from D.


You might be thinking "but I don't use = anything in this 
struct", but there's a few places where D will put one in 
automatically:

float and double = NaN by default
char, wchar, and dchar = -1 (well, 0xff) by default

And everything else =0 (or null) by default.


If *everything* in a struct is initialized to 0, the __init 
variable is left out and memset(&struct, struct.sizeof, 0) is 
called instead.

But if *anything* in there is non-zero, the __init variable is 
created and referenced when you declare the variable (unless you 
=void it at the usage point).


Which causes the undefined reference problem you're seeing - the 
usage code is trying to initialize, but the C library doesn't 
provide that (since it isn't a C feature) and the D library isn't 
linked in.



I betcha if you have any float/double or char variables in those 
structs and set them as =0 in the definition, you will actually 
be able to make this problem go away.


More information about the Digitalmars-d-learn mailing list