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.