On Tuesday, 25 May 2021 at 02:47:19 UTC, Gavin Ray wrote:

Unfortunately, it does not work if I try to add `final int getSomething()` or the other one to the D interfaces, it throws a symbol error because the mangled names are slightly different:

```sh

unresolved external symbol "public: int __cdecl Base1::getSomething(void)"
                  (?getSomething@Base1@@QEAAHXZ)
0000000000000000 T ?getSomething@Base1@@QEAA?BHXZ # < "nm" output
```

If I use `nm` and list the symbols, and then try to manually use the mangling scheme, it almost works but because the return types differ it won't compile =/
```d
extern class Derived : Base1, Base2
{
  int someInt;

  pragma(mangle, "?getOtherThing@Base2@@QEAA?BHXZ")
  int getOtherThing();
}
```

```sh
main.d(29): Error: Function type does not match previously declared function with the same mangled name: `?getOtherThing@Base2@@QEAA?BHXZ`
main.d(29):        Previous IR type: i32 (%main.Base2*)
main.d(29):        New IR type:      i32 (%main.Derived*)
```

That's just LDC thing, should work with DMD.
Are you sure `getOtherThing` marked final? Because in your C++ class it is not virtual and in your example it is not final as well. In C++ having multiple bases with final method means that both Base1 and Base2 have their own instances of that method.

Anyway in order to call it you'll have to cast manually to target base. i.e. if you want to call `Base1::getOtherThing` and you have `Derived` you'll have to cast to `Base1`.


```d
Derived d;
// d.getOtherThing(); // likely won't link
(cast(Base1)d) .getOtherThing(); // will call Base1 variant
(cast(Base2)d) .getOtherThing(); // will call Base2 variant
```

It is also possible that you'll have to put them in using mixin template so it will create scope for them that doesn't collide with each other, though I think it's more of a hack than a feature.

Something like
```d
class Derived
{
   mixin base1; // has final getOtherThing
   mixin base2; // has final getOtherThing
}
```

then you can call it almost like in C++
```d
d.base1.getOtherThing();
d.base2.getOtherThing();
```

Anyway all this stuff requires thorough research & testing as such ABI tinkering is very easy to mess up and very hard to debug, for example if you mess up the order(functions layout) it can land on another final method call that seemingly work but in debugger you'll see that you can't hit breakpoint in that method.
Happy debugging time!

Reply via email to