Using C++ Classes From D: dmd cannot link, while ldc segfault

mw mingwu at gmail.com
Mon Jun 19 05:20:56 UTC 2023


Hi,

I'm following this example:

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

and try to wrap a std::list

base.cpp
```cpp
#include <iostream>
#include <list>

using namespace std;

class Base
{
     public:
         virtual void print3i(int a, int b, int c) = 0;
};

class Derived : public Base
{
     public:
         int field;
         Derived(int field) : field(field) {}

         void print3i(int a, int b, int c)
         {
             cout << "a = " << a << endl;
             cout << "b = " << b << endl;
             cout << "c = " << c << endl;
         }

         int mul(int factor);
};

template<class T> class std_list : public std::list<T> {};
void getInts(std_list<int>* list);

int Derived::mul(int factor)
{
     return field * factor;
}

Derived *createInstance(int i)
{
     // get list of ints from D side
     std_list<int> list;
     list.push_back(911);
     ::getInts(&list);
     for (int i : list) {
             cout << "i = " << i << endl;
     }

     return new Derived(i);
}

void deleteInstance(Derived *&d)
{
     delete d;
     d = 0;
}
```

main.c
```
extern(C++)
{
     abstract class Base
     {
         void print3i(int a, int b, int c);
     }

     class Derived : Base
     {
         int field;
         @disable this();
         override void print3i(int a, int b, int c);
         final int mul(int factor);
     }

     Derived createInstance(int i);
     void deleteInstance(ref Derived d);
}

extern(C++) {

class std_list(T) {
   @disable this();
   void push_back(const ref T value);
}

void getInts(std_list!(int) list) {
   foreach (int i; 0 .. 10) {
     list.push_back(i);
   }
}

}

void main()
{
     import std.stdio;

     auto d1 = createInstance(5);
     writeln(d1.field);
     writeln(d1.mul(4));

     Base b1 = d1;
     b1.print3i(1, 2, 3);

     deleteInstance(d1);
     assert(d1 is null);

     auto d2 = createInstance(42);
     writeln(d2.field);

     deleteInstance(d2);
     assert(d2 is null);
}

```

Makefile
```
c2d:
	g++ -c -g -ggdb base.cpp
	ldmd2 -g main.d base.o -L-lstdc++ && ./main

```

if I use LCD (ldmd2), it segfaults:
```
$ make
g++ -c -g -ggdb base.cpp
ldmd2 -g main.d base.o -L-lstdc++ && ./main
Segmentation fault (core dumped)
```

and gdb shows it fails at: main.d:29 list.push_back(i);

if I use DMD, it cannot link:
```
$ make
g++ -c -g -ggdb base.cpp
dmd -g main.d base.o -L-lstdc++ && ./main
/usr/bin/ld: main.o:(.data._D4main__T8std_listTiZQm6__vtblZ+0x0): 
undefined reference to `std_list<int>::push_back(int const&)'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
```

Looks like something wrong with the push_back().

So, how to fix this DMD link error, and LDC segfaults?

Thanks.




More information about the Digitalmars-d-learn mailing list