www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Bind C++ class to DLang : undefined reference to `Canvas::Foo()'

reply zoujiaqing <zoujiaqing gmail.com> writes:
/// Canvas.hpp

#include <iostream>;

class Canvas
{
     static Canvas* Create();

     std::string Foo();

     std::string Bar();
};



/// Canvas.cpp

#include "Canvas.hpp"

#include <iostream>

Canvas* Canvas::Create()
{
     return new Canvas();
}

std::string Canvas::Foo()
{
     return "Foo";
}

std::string Canvas::Bar()
{
     return "Bar";
}



/// main.d

import std.stdio;

extern(C++)
{
     class Canvas
     {
          disable this();

         static Canvas Create();

         string Foo();

         string Bar();
     };
}

void main()
{
	Canvas canvas = Canvas.Create();

	writeln(canvas.Foo());

	writeln(canvas.Bar());
}





/usr/bin/ld: main.o:(.data._D4main6Canvas6__vtblZ+0x0): undefined 
reference to `Canvas::Foo()'
/usr/bin/ld: main.o:(.data._D4main6Canvas6__vtblZ+0x8): undefined 
reference to `Canvas::Bar()'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
Jul 12 2020
parent reply zoujiaqing <zoujiaqing gmail.com> writes:
I changed string to basic_string.

///  source/main.d
import std.stdio;
import core.stdcpp.string;

extern(C++)
{
     class Canvas
     {
          disable this();

         static Canvas Create();

         basic_string!ubyte Foo();

         basic_string!ubyte Bar();
     };
}

void main()
{
	Canvas canvas = Canvas.Create();

	writeln(canvas.Foo());

	writeln(canvas.Bar());
}

Error ...


[1]    49078 segmentation fault  ./main
Jul 13 2020
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 13 July 2020 at 09:34:35 UTC, zoujiaqing wrote:

 [1]    49078 segmentation fault  ./main
On my computer I got this warning out of the compiler: libstdc++ std::__cxx11::basic_string is not yet supported; the struct contains an interior pointer which breaks D move semantics! sounds like it might be a known limitation.
Jul 13 2020
parent reply zoujiaqing <zoujiaqing gmail.com> writes:
On Monday, 13 July 2020 at 12:57:52 UTC, Adam D. Ruppe wrote:
 On Monday, 13 July 2020 at 09:34:35 UTC, zoujiaqing wrote:

 [1]    49078 segmentation fault  ./main
On my computer I got this warning out of the compiler: libstdc++ std::__cxx11::basic_string is not yet supported; the struct contains an interior pointer which breaks D move semantics! sounds like it might be a known limitation.
Thanks Adam, but D link to C++ very hard?
Jul 13 2020
parent reply Boris Carvajal <boris2.9 gmail.com> writes:
On Monday, 13 July 2020 at 16:17:55 UTC, zoujiaqing wrote:
 On Monday, 13 July 2020 at 12:57:52 UTC, Adam D. Ruppe wrote:
 On Monday, 13 July 2020 at 09:34:35 UTC, zoujiaqing wrote:

 [1]    49078 segmentation fault  ./main
On my computer I got this warning out of the compiler: libstdc++ std::__cxx11::basic_string is not yet supported; the struct contains an interior pointer which breaks D move semantics! sounds like it might be a known limitation.
Thanks Adam, but D link to C++ very hard?
Can you try passing -D_GLIBCXX_USE_CXX11_ABI=0 to g++ and -version=_GLIBCXX_USE_CXX98_ABI to dmd. That comes from: https://dlang.org/changelog/2.088.0.html#std_string C++11 ABI is currently not supported.
Jul 13 2020
parent Jacob Carlborg <doob me.com> writes:
On 2020-07-14 05:33, Boris Carvajal wrote:

 Can you try passing -D_GLIBCXX_USE_CXX11_ABI=0 to g++ and 
 -version=_GLIBCXX_USE_CXX98_ABI to dmd.
 
 That comes from: https://dlang.org/changelog/2.088.0.html#std_string
 
 C++11 ABI is currently not supported.
I based on previous messages and the usage of Clang, I think zoujiaqing is using a Mac. On Mac libc++ is used. That above might not apply. -- /Jacob Carlborg
Jul 15 2020
prev sibling parent evilrat <evilrat666 gmail.com> writes:
On Monday, 13 July 2020 at 09:34:35 UTC, zoujiaqing wrote:
 I changed string to basic_string.

 ///  source/main.d
 import std.stdio;
 import core.stdcpp.string;

 extern(C++)
 {
     class Canvas
     {
          disable this();

         static Canvas Create();

         basic_string!ubyte Foo();

         basic_string!ubyte Bar();
     };
 }

 void main()
 {
 	Canvas canvas = Canvas.Create();

 	writeln(canvas.Foo());

 	writeln(canvas.Bar());
 }

 Error ...


 [1]    49078 segmentation fault  ./main
Putting std::string support aside there is another issue in this example. D has virtual by default semantic unlike C++. One possible segfault reason is that because it tries to call non existing virtual method. Marking those D methods 'final' should fix linking issues. Also I can't remember if extern(C++) is implicitly propagated to class methods so I would put extern(C++) in class body just to be sure.
Jul 13 2020