On Monday, 13 December 2021 at 09:21:26 UTC, Jan wrote:
> On Monday, 13 December 2021 at 07:48:34 UTC, evilrat wrote:
> On Sunday, 12 December 2021 at 21:24:39 UTC, Jan wrote:
> In D I have an extern(C++) class:
extern(C++) class A
{
~this();
// other stuff
}
An a function that takes A by const reference:
void CppFunc(const A& arg);
But how do I bind this in D ?
extern(C++) void CppFunc(A arg); // tries to pass as 'A*'
extern(C++) void CppFunc(ref const(A) arg); // tries to pass as 'A const * const &'
I have solved similar problems with other classes by declaring them as struct in D, but that only works for classes that have no virtual functions. I now have a class where I do need to use a class on the D side, and now I have problems passing these objects to C++.
You can tell compiler to mangle it as struct/class using extern(C++, struct).
extern (C++, struct) // will use struct mangling even though it's a class
class SomeDClass
{
...
}
I tried this, but it doesn't work, because it seems D decides how to pass the object by whether it is a class or struct in D, not in C++. So even with the change as you suggested it, it still tries to pass the object as a pointer to begin with.
You'll have to use something called a shim, it seems.
For example:
main.d
:
extern(C++) class A{}
extern(C++) void cppFunc_shim(A arg);
void main(){
A a = new A();
cppFunc_shim(a);
}
cppShim.cpp
:
class A{};
extern void cppFunc(A const &arg);
void cppFunc_shim(A *param){
const A forwardingVar = A(*param);
cppFunc(forwardingVar);
}
cppFunc.cpp
:
#include "iostream"
class A{};
void cppFunc(A const &arg){
//std::cout << arg << std::endl;
std::cout << "Called cppFunc :D" << std::endl;
}
Then pass the following on the command line(assuming all files are in the same directory):
ldmd2 main.d cppFunc.o cppShim.o -L-lstdc++
That's what it took to make it work for me, dunno if more convenient methods exist.
Hope it helps :D