extern(C) and mangling type names

Timothee Cour via Digitalmars-d digitalmars-d at puremagic.com
Tue Feb 14 20:55:53 PST 2017


I should've said 'related', not actually a dup. Walter, could you please
shed some light on this other thread?

Any workaround in the meantime would be highly appreciated

http://forum.dlang.org/thread/mailman.445.1487070970.31550.digitalmars-d@puremagic.com
pragma(mangle,"name") for a type?




On Tue, Feb 14, 2017 at 8:51 PM, Timothee Cour <thelastmammoth at gmail.com>
wrote:

> looks like a dup of this:
> http://forum.dlang.org/thread/mailman.445.1487070970.31550.
> digitalmars-d at puremagic.com pragma(mangle,"name") for a type?
>
>
>
>
> On Tue, Feb 14, 2017 at 7:40 PM, Mike Parker via Digitalmars-d <
> digitalmars-d at puremagic.com> 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?
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20170214/05c16684/attachment-0001.html>


More information about the Digitalmars-d mailing list