On Thursday, 24 January 2013 at 09:39:39 UTC, Sarath Kumar wrote:
On Thursday, 24 January 2013 at 09:04:09 UTC, Mike Parker wrote:

The error message here is deceiving. Declare the struct in one module only and then import it in every module that uses it. So, for example, keep the declaration in libA, remove it from libB and in libB add "import libA;".

I can't import libA into libB. So, I had moved the forward declaration into a separate D file and did a public import into libA and libB. This works. But this is a workaround. I will file a bug.


The only potential bug I see here is in the error message. What you're seeing is a conflict that arises from D's name mangling. The doSomething in libA is expecting a parameter of type libA.Opaque* and getObject is returning the same, whereas the functions in libB are expecting a parameter of type libB.Opaque*. You can see this if you do the following:

writeln(doSomething.mangleof);
writeln(doAction.mangleof);

This is why your code is failing when you call getAction, because you're passing it a libA.Opaque* returned from libA.getObject. The solution is to declare opaque struct in a single place and import it everywhere you need it. That's why your public imports work. I would suggest that you not use the public import in this case, but work out some other scenario. In Derelict (a collection of C bindings) for example, I tend to follow this pattern for any lib a bind to:

types.d <- all type & constant declarations go here
functions.d <- all function declarations go here, imports the types module

Then I have a module named according to the C library's primary header that publicly imports both. For SDL2, for example:

module derelict.sdl2.sdl;

public {
    import derelict.sdl2.types;
    import derelict.sdl2.functions;
}

This way, all types are declared in a single location so there's no danger of mixing up different mangles of the same type.

Reply via email to