Fun with extern(C++)

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Tue Jan 26 09:43:36 PST 2016


On 1/26/16 10:57 AM, Manu via Digitalmars-d wrote:
> On 27 January 2016 at 01:38, Steven Schveighoffer via Digitalmars-d
> <digitalmars-d at puremagic.com> wrote:
>> On 1/26/16 8:58 AM, Jacob Carlborg wrote:
>>>
>>> On 2016-01-26 13:59, Manu via Digitalmars-d wrote:
>>>
>>>> Hmmm. I wonder if this will cause problems...
>>>> Is it impossible to support a C++ class implementing a D interface?
>>>
>>>
>>> No that I know how the C++ compatibility works but I would guess the
>>> compiler needs to know at compile time how to call a method. If it would
>>> be possible to implement a D interface as either a D class or C++ class.
>>> The compiler cannot know which runtime type a variable which is declared
>>> as an interface can hold.
>>>
>>> interface A { void foo(); }
>>> class B : A { void foo(); }
>>> extern(C++) class C : A { void foo(); } // assuming this works
>>>
>>> A a = new B;
>>> A b = new C; // assuming this works
>>>
>>> a.foo();
>>> b.foo();
>>>
>>> When the compiler sees "a" or "b", how should it know it should call
>>> "foo" as a D method or C++ method? It only knows about the static type
>>> which is A, a D interface.
>>>
>>
>> The short answer to this question is, no you cannot. The layouts are
>> different. It's why I have always said, D interfaces should implicitly
>> convert to Object and support all Object methods. Only D classes can
>> implement D interfaces.
>
> Interface is just a vtable... what makes the layout different?
> Surely any class can take a vtable definition and populate it with
> some function pointers.

I believe the D interface mechanism depends on the vtable layout being a 
certain way in the object. The C++ layout conflicts with that.

I could imagine one could construct an appropriate TypeInfo pointer 
inside the C++ class, with the proper offset stored in a mock TypeInfo 
class, such that you could actually get the virtual function to call. 
But you would run into other problems. For example, if you wanted to 
cast to another interface, you would likely segfault.

This would be a nightmare to do in a library.

-Steve


More information about the Digitalmars-d mailing list