How does inheritance and vtables work wrt. C++ and interop with D? Fns w/ Multiple-inheritance args impossible to bind to?

Gavin Ray gavinray at site.com
Sun May 23 21:02:31 UTC 2021


On Sunday, 23 May 2021 at 20:16:17 UTC, Ola Fosheim Grostad wrote:
> On Sunday, 23 May 2021 at 19:44:01 UTC, Gavin Ray wrote:
>> So one of the problems with generating D code for bindings to 
>> C++ is that there's no true/direct multiple inheritance.
>>
>> If anyone happens to understand well how vtables work and the 
>> way the compiler treats these things, is there a way to 
>> hackily make semantically-equivalent objects?
>
> I believe Clang and MSVC are using different layouts.
> If I am not wrong clang/gcc are using the Itanium ABI, but I 
> could be wrong.
>
> https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable
>
> Maybe ask in the LDC forum as they follow Clang? In my opinion 
> MI ought to be supported for binding, but... not sure if anyone 
> has considered it.

I guess that's maybe a better way of what I'm asking -- whether 
the vtable is all that matters.

Because I've seen C ABI's for C++ API's that have multiple 
inheritance, and the code was like this (I'll just post a single 
inheritance example but you get the point):

```cpp
class FUnknown {
     tresult queryInterface(void*, const TUID, void**);
     uint32* addRef(void *);
     uint32* release(void *);
};

class IComponentHandler : FUnknown {
     tresult beginEdit(void *, ParamID);
     tresult performEdit(void *, ParamID, ParamValue);
     tresult endEdit(void *, ParamID);
     tresult restartComponent(void *, int32);
};

#ifdef __cplusplus
extern "C" {
#endif
typedef struct FUnknownVTable {
     tresult (*queryInterface)(void *, const TUID, void **);
     uint32 (*addRef)(void *);
     uint32 (*release)(void *);
} FUnknownVTable;

typedef struct SFUnknown {
     FUnknownVTable *vtable;
} SFUnknown;

typedef struct IComponentHandlerVTable {
     FUnknownVTable FUnknown;
     tresult (*beginEdit)(void *, ParamID);
     tresult (*performEdit)(void *, ParamID, ParamValue);
     tresult (*endEdit)(void *, ParamID);
     tresult (*restartComponent)(void *, int32);
} IComponentHandlerVTable;

typedef struct SIComponentHandler {
     IComponentHandlerVTable *vtable;
} SIComponentHandler;

#ifdef __cplusplus
}
#endif
```

I don't really know anything at all about compilers or low-level 
code -- but is there any high-level notion of "inheritance" after 
it's been compiled?

I felt like it had to turn into something like blocks of memory 
that have pointers to methods and/or to other blocks of memory 
with pointers to methods (vtables). But I also have no clue 🤔




More information about the Digitalmars-d-learn mailing list