Thread overview
How to call a extern C++ class constructor ?
Feb 01, 2020
Luhrel
Feb 01, 2020
Ferhat Kurtulmuş
Feb 01, 2020
Luhrel
Feb 01, 2020
Ferhat Kurtulmuş
Feb 01, 2020
Luhrel
Feb 01, 2020
norm
Feb 01, 2020
Ferhat Kurtulmuş
Feb 01, 2020
kinke
Feb 01, 2020
kinke
February 01, 2020
Hello there,

I would like to know how can I call a C++ ctor.

Actually, I have this:

C++:
CppClass.cpp
----------------
#include "CppClass.h"


AmazingCppClass::AmazingCppClass()
{
	number = 124;
}

int AmazingCppClass::getNumber(bool show)
{
	if (show)
		printf("Number: %s", number);
	return number;
}

void AmazingCppClass::add(int num)
{
	number += num;
}
----------------
CppClass.h:
----------------
#include <stdio.h>


class AmazingCppClass
{
private:
	int number;

public:
	AmazingCppClass();
	int getNumber(bool show);
	void add(int num);
};
----------------

D:
app.d
----------------
import std.stdio;

void main()
{
	auto dcpp = new AmazingCppClass();
	dcpp.getNumber(true); //segfault here
}

extern(C++) class AmazingCppClass
{
	this();

	int getNumber(bool show);

	void add(int num);
}
----------------

But somehow I got a segfault on dcpp.getNumber(true).
I found that there's a __cpp_new (https://dlang.org/phobos/core_stdcpp_new_.html), but I have no idea how to use it and the doc doesn't say a lot about this (https://dlang.org/spec/cpp_interface.html#using_cpp_classes_from_d)

Do you guys know ?
February 01, 2020
On Saturday, 1 February 2020 at 08:15:20 UTC, Luhrel wrote:
> Hello there,
>
> I would like to know how can I call a C++ ctor.
>
> [...]

You cannot. https://dlang.org/spec/cpp_interface.html#using_cpp_classes_from_d

You must use a factory method like createInstance.
February 01, 2020
On Saturday, 1 February 2020 at 08:21:29 UTC, Ferhat Kurtulmuş wrote:
>
> You cannot. https://dlang.org/spec/cpp_interface.html#using_cpp_classes_from_d
>
> You must use a factory method like createInstance.

Oh I see, so there's definitively no way to call a c++ ctor without modifying the c++ code ?
February 01, 2020
On Saturday, 1 February 2020 at 08:27:07 UTC, Luhrel wrote:
> On Saturday, 1 February 2020 at 08:21:29 UTC, Ferhat Kurtulmuş wrote:
>>
>> You cannot. https://dlang.org/spec/cpp_interface.html#using_cpp_classes_from_d
>>
>> You must use a factory method like createInstance.
>
> Oh I see, so there's definitively no way to call a c++ ctor without modifying the c++ code ?

İf you are not allowed to modify that c++ code, you can write a createInstance function in your custom cpp file.
February 01, 2020
On Saturday, 1 February 2020 at 08:32:51 UTC, Ferhat Kurtulmuş wrote:
> On Saturday, 1 February 2020 at 08:27:07 UTC, Luhrel wrote:
>> On Saturday, 1 February 2020 at 08:21:29 UTC, Ferhat Kurtulmuş wrote:
>>>
>>> You cannot. https://dlang.org/spec/cpp_interface.html#using_cpp_classes_from_d
>>>
>>> You must use a factory method like createInstance.
>>
>> Oh I see, so there's definitively no way to call a c++ ctor without modifying the c++ code ?
>
> İf you are not allowed to modify that c++ code, you can write a createInstance function in your custom cpp file.

That was my fear.
February 01, 2020
On Saturday, 1 February 2020 at 08:38:22 UTC, Luhrel wrote:
> On Saturday, 1 February 2020 at 08:32:51 UTC, Ferhat Kurtulmuş wrote:
>> On Saturday, 1 February 2020 at 08:27:07 UTC, Luhrel wrote:
>>> On Saturday, 1 February 2020 at 08:21:29 UTC, Ferhat Kurtulmuş wrote:
>>>>
>>>> You cannot. https://dlang.org/spec/cpp_interface.html#using_cpp_classes_from_d
>>>>
>>>> You must use a factory method like createInstance.
>>>
>>> Oh I see, so there's definitively no way to call a c++ ctor without modifying the c++ code ?
>>
>> İf you are not allowed to modify that c++ code, you can write a createInstance function in your custom cpp file.
>
> That was my fear.

It isn't too bad, you need a simple wedge written in C++ that returns an instance of any T you want. A simple template function usually works, or to make it more generic you can use a variadic template to handle N args, but I find variadic templates in C++ are still annoying to use.
February 01, 2020
On Saturday, 1 February 2020 at 10:21:54 UTC, norm wrote:
> On Saturday, 1 February 2020 at 08:38:22 UTC, Luhrel wrote:
>> On Saturday, 1 February 2020 at 08:32:51 UTC, Ferhat Kurtulmuş wrote:
>>> On Saturday, 1 February 2020 at 08:27:07 UTC, Luhrel wrote:
>>>> On Saturday, 1 February 2020 at 08:21:29 UTC, Ferhat Kurtulmuş wrote:
>>>>> [...]
>>>>
>>>> Oh I see, so there's definitively no way to call a c++ ctor without modifying the c++ code ?
>>>
>>> İf you are not allowed to modify that c++ code, you can write a createInstance function in your custom cpp file.
>>
>> That was my fear.
>
> It isn't too bad, you need a simple wedge written in C++ that returns an instance of any T you want. A simple template function usually works, or to make it more generic you can use a variadic template to handle N args, but I find variadic templates in C++ are still annoying to use.

And do not forget to write a void cppDestroy(T instance) function that runs delete instance in c++ so that you can call it from D code.

void cppDestroy(T instance)
February 01, 2020
On Saturday, 1 February 2020 at 08:15:20 UTC, Luhrel wrote:
> But somehow I got a segfault on dcpp.getNumber(true).

That's because you declare it as virtual in D (default for classes, use `final`), but non-virtual in C++. You also forgot to add the class field to the D declaration (yes, D needs to know about the struct layout and size too, especially when you `new` the class in D and let the GC allocate it).

Trivial cases like yours should actually work wrt. using C++ ctor implementations from D IIRC.
February 01, 2020
On Saturday, 1 February 2020 at 14:52:21 UTC, kinke wrote:
> Trivial cases like yours should actually work wrt. using C++ ctor implementations from D IIRC.

Ah, you need at least one virtual function in the C++ class (because D always reserves a vptr, the pointer to the class vtable).