www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to call a extern C++ class constructor ?

reply Luhrel <lucien.perregaux gmail.com> writes:
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 ?
Feb 01 2020
next sibling parent reply Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
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.
Feb 01 2020
parent reply Luhrel <lucien.perregaux gmail.com> writes:
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 ?
Feb 01 2020
parent reply Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
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.
Feb 01 2020
parent reply Luhrel <lucien.perregaux gmail.com> writes:
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.
Feb 01 2020
parent reply norm <norm.rowtree gmail.com> writes:
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.
Feb 01 2020
parent Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
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)
Feb 01 2020
prev sibling parent reply kinke <noone nowhere.com> writes:
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.
Feb 01 2020
parent kinke <noone nowhere.com> writes:
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).
Feb 01 2020