How to pass a class by (const) reference to C++

Tejas notrealemail at gmail.com
Mon Dec 13 11:13:12 UTC 2021


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:
>>>
>>> ```cpp
>>> extern(C++) class A
>>> {
>>>     ~this();
>>>
>>>     // other stuff
>>> }
>>> ```
>>>
>>> An a function that takes A by const reference:
>>>
>>> ```cpp
>>> void CppFunc(const A& arg);
>>> ```
>>>
>>> But how do I bind this in D ?
>>>
>>> ```cpp
>>> 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).
>>
>> ```d
>> 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](https://en.wikipedia.org/wiki/Shim_(computing)), it seems.

For example:

`main.d` :

```d

extern(C++) class A{}

extern(C++) void cppFunc_shim(A arg);

void main(){
	A a = new A();
	cppFunc_shim(a);
}

```

`cppShim.cpp` :

```c++

class A{};

extern void cppFunc(A const &arg);

void cppFunc_shim(A *param){
	const A forwardingVar = A(*param);
	cppFunc(forwardingVar);
}

```

`cppFunc.cpp` :

```c++

#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



More information about the Digitalmars-d-learn mailing list