looks like a dup of this: http://forum.dlang.org/thread/[email protected] pragma(mangle,"name") for a type?
On Tue, Feb 14, 2017 at 7:40 PM, Mike Parker via Digitalmars-d < [email protected]> wrote: > ``` > module mang; > extern(C): > struct Foo; > void bar(); > int x; > > pragma(msg, Foo.mangleof); > pragma(msg, bar.mangleof); > pragma(msg, x.mangleof); > ``` > > Obviously, x and bar are seen by the linker and mangling is turned off for > them. I've always believed it was the same for type declarations as well. > Alas, that is not the case. > > The use case I'm looking at here is forward references (opaque types). > Works fine when binding to C libraries. Or even with other D modules when > written like this: > > > ``` > module ec1; > extern(C): > struct Foo; > Foo* newFoo(int x); > void printFoo(Foo* f); > > module ec2; > extern(C): > struct Foo { int x; } > Foo* newFoo(int x) { return new Foo(x); } > void printFoo(Foo* f) { import std.stdio; writeln(f.x); } > > module ec3; > void main() { > import ec1; > Foo* f = newFoo(30); > printFoo(f); > } > ``` > > This compiles and runs. Now change ec1 and ec3 like so: > > ``` > module ec1; > extern(C) struct Foo; > > module ec3; > void main() { > import ec1, ec2; > Foo* f = newFoo(30); > printFoo(f); > } > ``` > > This produces the following errors: > > ec3.d(4): Error: ec1.Foo at ec1.d(2) conflicts with ec2.Foo at ec2.d(3) > ec3.d(4): Error: cannot implicitly convert expression (newFoo(30)) of type > Foo* to Foo* > ec3.d(5): Error: function ec2.printFoo (Foo* f) is not callable using > argument types (Foo*) > > IMO, extern(C) should turn off mangling for Foo. It would make forward > references useful outside of the specific case of C bindings. > > Consider the situation where you want to call a user-defined function (not > a function pointer or a delegate). It's easy to do by providing an > extern(C) prototype and requiring the user to use extern(C) in the > implementation. The same thing should be possible for types. > > My specific use case is a binding to a C library that makes use of > specific types from X11, Wayland and elsewhere. I don't want to force a > specific binding upon the user, so I need to declare the relevant types in > a way that is binding-neutral. One option, of course, is to use void*, > which has a lack of type safety and requires casting all over the place. > Another is to wrap the declarations up in mixin templates and have the user > mix them where they've imported the specific binding. Less onerous than > void*, but still not ideal. > > So, should extern(C) turn off mangling for types? >
