Calling C++ "void foo(Klass&)"

Walter Bright via Digitalmars-d digitalmars-d at puremagic.com
Wed Aug 9 11:43:27 PDT 2017


On 8/8/2017 2:04 PM, Jacob Carlborg wrote:
> On 2017-08-08 20:51, Johan Engelen wrote:
>> Hi all,
>>    Currently, it is not possible to call the C++ function "void
>> foo(Klass&)" when Klass is an extern(C++) _class_ on the D side. You
>> have to declare Klass as a D _struct_, otherwise there is no way to get
>> the correct mangling. When Klass has virtual functions, you're hosed.
>>
>> For more context (involving "const"), see:
>> https://forum.dlang.org/post/tvohflgtaxlynpzedqky@forum.dlang.org
>>
>> Is this problem on anybody's radar?
>> What are the ideas to resolve this issue, or are we content never to
>> solve it?
> 
> One way to do it, that might be a bit confusing, is to force the declaration of 
> the function to explicitly specify a pointer or a reference. Currently it looks 
> like it's an implicit pointer.
> 
> extern (C++) class Klass {}
> void foo(Klass*); // ok
> void foo(ref Klass); // ok
> void foo(Klass); // error
> 
> Of course, there's always pragma(mangle) as well.

As Jacob hints at, the C++ name mangling for Klass* and Klass& is different. D 
classes are implicitly by reference. So which mangling to choose? D chose the 
Klass*.

The best way to deal with that is, on the C++ side, add:

     void foo(Klass* k) { foo(*k); }


On a more philosophical note, D makes a hard distinction between struct and 
class - struct is a value type, class is a reference type. In C++ the 
characteristics of each can be mixed and matched, not so in D. Interfacing D to 
such chimera types is going to need a bit of flexibility on the C++ side, such 
as writing a trampoline like the above.


More information about the Digitalmars-d mailing list