www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - cpp header bindings

reply Rui Justino <rmcjustino gmail.com> writes:
hi
Hive been trying to create a simple interface to a also simple c++ header file.
Any help is appreciated since I've been for several days trying to solve this
using different approaches but unsuccessfully(D newbie).
----------------------------------------
The header file "thetest.h":
#ifndef THETEST_H
#define THETEST_H
class TheTest
{
public:
    TheTest (int);
    void myfirst ( int myf );
    void mysecond ( int myff );
    ~TheTest();
private:
    int p_Myf;
    int p_Myff;
    int p_Mytotal;
};
----------------------------------------
The cpp file "thetest.cpp":
#include "thetest.h"
#include <iostream>
using namespace std;
  TheTest::TheTest (int mytot)
  {
    p_Mytotal = mytot;
  }
  TheTest::~TheTest()
  {
  }
  void TheTest::myfirst (int myf) {
    p_Myf = myf;
    cout << p_Mytotal << endl;
    cout << p_Myf << endl;
  }
  void TheTest::mysecond ( int myff ) {
    p_Myff = myff;
    cout << p_Myff << endl;
  }
-------------------------------------------------------------------------------------
The interface created by BCD "thetest.d":
/* THIS FILE GENERATED BY bcd.gen */                              
module bcd.my4.thetest;                                           
align(4):                                                         
public import bcd.bind;                                           
public import bcd.my4.thetest;                                     
extern (C) void _BCD_delete_7TheTest(void *);                     
extern (C) void *_BCD_new__ZN7TheTestC1Ei(int);                   
extern (C) void _BCD__ZN7TheTest7myfirstEi(void *This, int);      
extern (C) void _BCD__ZN7TheTest8mysecondEi(void *This, int);     
extern (C) void _BCD_RI_7TheTest(void *cd, void *dd);             
extern (C) void _BCD_delete_7TheTest__TheTest_R(void *This);      
extern (C) void *_BCD_new__ZN7TheTestC1Ei_R(int);                 
class TheTest : bcd.bind.BoundClass {                             
this(ifloat ignore) {                                             
super(ignore);                                                    
}                                                                 
this(ifloat ignore, void *x) {                                    
super(ignore);                                                    
__C_data = x;                                                     
__C_data_owned = false;
}
~this() {
if (__C_data && __C_data_owned) _BCD_delete_7TheTest(__C_data);
__C_data = null;
}
this(int _0) {
super(cast(ifloat) 0);
__C_data = _BCD_new__ZN7TheTestC1Ei(_0);
__C_data_owned = true;
}
void myfirst(int myf) {
_BCD__ZN7TheTest7myfirstEi(__C_data, myf);
}
void mysecond(int myff) {
_BCD__ZN7TheTest8mysecondEi(__C_data, myff);
}
}
class TheTest_R : TheTest {
~this() {
if (__C_data && __C_data_owned) _BCD_delete_7TheTest__TheTest_R(__C_data);
__C_data = null;
}
this(int _0) {
super(cast(ifloat) 0);
__C_data = _BCD_new__ZN7TheTestC1Ei_R(_0);
__C_data_owned = true;
_BCD_RI_7TheTest(__C_data, cast(void *) this);
}}
----------------------------------------------------------------------------------------------------------------------
D module "header_tit.d":
import bcr = bcd.my4.thetest;

void main()
{
  int a=6;
  int b=7;

 bcr.TheTest myts = new bcr.TheTest (a+b);
 //myts.my_first(a);
 //myts.my_second(b);
}
----------------------------------------------------------------------------------------
I then compile this using:
g++ thetest.cpp -c
#gdmd header_tit.d thetest.o -L-lstdc++
    header_tit.o: In function `_Dmain': 
   header_tit.d:(.text+0x20): undefined reference to     
`_D7thetest7TheTest7__ClassZ'
    header_tit.d:(.text+0x2f): undefined reference to
`_D7thetest7TheTest5_ctorMUiZC7thetest7TheTest'
    collect2: ld returned 1 exit status
----------------------------------------------------------------------------------------
Even with an interface create by me for d header file
file "thetest.d":
extern (C) {
class TheTest
{
public:
    this (int);
    void myfirst ( int myf );
    void mysecond ( int myff );
    ~this();
private:
    int p_Myf;
    int p_Myff;
    int p_Mytotal;
}}
----------------------------------------------------------------------------------------
making the needed changes in header_tit.d the output is the same
#gdmd header_tit.d thetest.o -L-lstdc++
header_tit.o: In function `_Dmain':
header_tit.d:(.text+0x20): undefined reference to `_D7thetest7TheTest7__ClassZ'
header_tit.d:(.text+0x2f): undefined reference to
`_D7thetest7TheTest5_ctorMUiZC7thetest7TheTest'
collect2: ld returned 1 exit status
----------------------------------------------------------------------------------------
The gdc version (this is a costume gentoo version the last one on svn):
#gdc -v
Using built-in specs.
Target: x86_64-pc-linux-gnu
Configured with: /var/tmp/portage/sys-devel/gcc-4.1.2/work/gcc-4.1.2/configure
--prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.1.2
--includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include
--datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.1.2
--mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.1.2/man
--infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.1.2/info
--with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4
--host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec
--enable-nls --without-included-gettext --with-system-zlib --disable-checking
--disable-werror --enable-secureplt --enable-multilib --disable-libmudflap
--disable-libssp --disable-libgcj --enable-languages=c,c++,d,treelang
--enable-shared --enable-threads=posix --enable-__cxa_atexit
--enable-clocale=gnu
Thread model: posix
gcc version 4.1.2 20070214 ( gdc 0.24, using dmd 1.030) (Gentoo 4.1.2 p1.1)
Or on debian:
hi
Hive been trying to create a simple interface to a also simple c++ header file.
Any help is appreciated since I've been for several days trying to solve this
using different approaches but unsuccessfully.
----------------------------------------
The header file "thetest.h":
#ifndef THETEST_H
#define THETEST_H
class TheTest
{
public:
    TheTest (int);
    void myfirst ( int myf );
    void mysecond ( int myff );
    ~TheTest();
private:
    int p_Myf;
    int p_Myff;
    int p_Mytotal;
};
----------------------------------------
The cpp file "thetest.cpp":
#include "thetest.h"
#include <iostream>
using namespace std;
  TheTest::TheTest (int mytot)
  {
    p_Mytotal = mytot;
  }
  TheTest::~TheTest()
  {
  }
  void TheTest::myfirst (int myf) {
    p_Myf = myf;
    cout << p_Mytotal << endl;
    cout << p_Myf << endl;
  }
  void TheTest::mysecond ( int myff ) {
    p_Myff = myff;
    cout << p_Myff << endl;
  }
-------------------------------------------------------------------------------------
The interface created by BCD "thetest.d":
/* THIS FILE GENERATED BY bcd.gen */                              
module bcd.my4.thetest;                                           
align(4):                                                         
public import bcd.bind;                                           
public import bcd.my4.thetest;                                     
extern (C) void _BCD_delete_7TheTest(void *);                     
extern (C) void *_BCD_new__ZN7TheTestC1Ei(int);                   
extern (C) void _BCD__ZN7TheTest7myfirstEi(void *This, int);      
extern (C) void _BCD__ZN7TheTest8mysecondEi(void *This, int);     
extern (C) void _BCD_RI_7TheTest(void *cd, void *dd);             
extern (C) void _BCD_delete_7TheTest__TheTest_R(void *This);      
extern (C) void *_BCD_new__ZN7TheTestC1Ei_R(int);                 
class TheTest : bcd.bind.BoundClass {                             
this(ifloat ignore) {                                             
super(ignore);                                                    
}                                                                 
this(ifloat ignore, void *x) {                                    
super(ignore);                                                    
__C_data = x;                                                     
__C_data_owned = false;
}
~this() {
if (__C_data && __C_data_owned) _BCD_delete_7TheTest(__C_data);
__C_data = null;
}
this(int _0) {
super(cast(ifloat) 0);
__C_data = _BCD_new__ZN7TheTestC1Ei(_0);
__C_data_owned = true;
}
void myfirst(int myf) {
_BCD__ZN7TheTest7myfirstEi(__C_data, myf);
}
void mysecond(int myff) {
_BCD__ZN7TheTest8mysecondEi(__C_data, myff);
}
}
class TheTest_R : TheTest {
~this() {
if (__C_data && __C_data_owned) _BCD_delete_7TheTest__TheTest_R(__C_data);
__C_data = null;
}
this(int _0) {
super(cast(ifloat) 0);
__C_data = _BCD_new__ZN7TheTestC1Ei_R(_0);
__C_data_owned = true;
_BCD_RI_7TheTest(__C_data, cast(void *) this);
}
}
----------------------------------------------------------------------------------------------------------------------
D module "header_tit.d":
import bcr = bcd.my4.thetest;

void main()
{
  int a=6;
  int b=7;

 bcr.TheTest myts = new bcr.TheTest (a+b);
 //myts.my_first(a);
 //myts.my_second(b);
}
----------------------------------------------------------------------------------------
I then compile this using:
g++ thetest.cpp -c
#gdmd header_tit.d thetest.o -L-lstdc++
    header_tit.o: In function `_Dmain': 
   header_tit.d:(.text+0x20): undefined reference to     
`_D7thetest7TheTest7__ClassZ'
    header_tit.d:(.text+0x2f): undefined reference to
`_D7thetest7TheTest5_ctorMUiZC7thetest7TheTest'
    collect2: ld returned 1 exit status
----------------------------------------------------------------------------------------
Even with an interface create by me for d header file
file "thetest.d":
extern (C) {
class TheTest
{
public:
    this (int);
    void myfirst ( int myf );
    void mysecond ( int myff );
    ~this();
private:
    int p_Myf;
    int p_Myff;
    int p_Mytotal;
}}
----------------------------------------------------------------------------------------
making the needed changes in header_tit.d the output is the same
#gdmd header_tit.d thetest.o -L-lstdc++
header_tit.o: In function `_Dmain':
header_tit.d:(.text+0x20): undefined reference to `_D7thetest7TheTest7__ClassZ'
header_tit.d:(.text+0x2f): undefined reference to
`_D7thetest7TheTest5_ctorMUiZC7thetest7TheTest'
collect2: ld returned 1 exit status
----------------------------------------------------------------------------------------
The gdc version:
#gdc -v
Using built-in specs.
Target: x86_64-pc-linux-gnu
Configured with: /var/tmp/portage/sys-devel/gcc-4.1.2/work/gcc-4.1.2/configure
--prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.1.2
--includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include
--datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.1.2
--mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.1.2/man
--infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.1.2/info
--with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4
--host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec
--enable-nls --without-included-gettext --with-system-zlib --disable-checking
--disable-werror --enable-secureplt --enable-multilib --disable-libmudflap
--disable-libssp --disable-libgcj --enable-languages=c,c++,d,treelang
--enable-shared --enable-threads=posix --enable-__cxa_atexit
--enable-clocale=gnu
Thread model: posix
gcc version 4.1.2 20070214 ( gdc 0.24, using dmd 1.030) (Gentoo 4.1.2 p1.1)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#gdc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,d --prefix=/usr
--enable-shared --with-system-zlib --libexecdir=/usr/lib
--without-included-gettext --enable-threads=posix --enable-nls
--with-gxx-include-dir=/usr/include/c++/4.1.3 --program-suffix=-4.1
--enable-__cxa_atexit --enable-clocale=gnu --disable-libmudflap
--enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.3 20080623 (prerelease gdc 0.25 20080419, using dmd 1.024)
(Debian 0.25-20080616-4.1.2-23)

any comment is appreciated. sorry for a so long post
Jul 29 2008
parent reply RCJ <rmcjustino gmail.com> writes:
Rui Justino Wrote:

Well once more sorry for the very long post.
Let me try to clarify the problem. I'm trying to create an interface from cpp
to d with the following files.

./bcd/my4/thetest.d
./thetest.h
./thetest.cpp
./thetest.d
./header_tit.d

cpp files are working, but when i try to create bindings to that header file i
get to a point were i receive the same error using 2 different approaches. For
the binding there are two files, one created by BCD and the other by h2d
("./thetest.d" and "./bcd/my4/thetest.d").
With this 2 different approaches I receive the same exact error message, in 2
different versions of GDC.

I would be grateful if some one could show me my error.
 ----------------------------------------------------------------------------------------
 #gdmd header_tit.d thetest.o -L-lstdc++
 header_tit.o: In function `_Dmain':
 header_tit.d:(.text+0x20): undefined reference to `_D7thetest7TheTest7__ClassZ'
 header_tit.d:(.text+0x2f): undefined reference to
`_D7thetest7TheTest5_ctorMUiZC7thetest7TheTest'
 collect2: ld returned 1 exit status
 ----------------------------------------------------------------------------------------
Jul 29 2008
parent "Bill Baxter" <wbaxter gmail.com> writes:
Interop with C++ is a fairly new addition to the language, and only in
D2 I believe.  I don't think either bcd or htod know how to handle
C++. So they're not likely to work.

In your hand-wrapping of the C++ you do this:

"""
extern (C) {
class TheTest
{
public:
  this (int);
  void myfirst ( int myf );
  void mysecond ( int myff );
  ~this();
private:
  int p_Myf;
  int p_Myff;
  int p_Mytotal;
}}
"""

Which has little chance of working since classes don't have any
meaning in C.  It might work using extern(C++) with a D2 compiler.
I've not done much with D2, though (no Tango, no DWT), so I couldn't
say for sure.

--bb

On Wed, Jul 30, 2008 at 2:33 PM, RCJ <rmcjustino gmail.com> wrote:
 Rui Justino Wrote:

 Well once more sorry for the very long post.
 Let me try to clarify the problem. I'm trying to create an interface from cpp
to d with the following files.

 ./bcd/my4/thetest.d
 ./thetest.h
 ./thetest.cpp
 ./thetest.d
 ./header_tit.d

 cpp files are working, but when i try to create bindings to that header file i
get to a point were i receive the same error using 2 different approaches. For
the binding there are two files, one created by BCD and the other by h2d
("./thetest.d" and "./bcd/my4/thetest.d").
 With this 2 different approaches I receive the same exact error message, in 2
different versions of GDC.

 I would be grateful if some one could show me my error.
 ----------------------------------------------------------------------------------------
 #gdmd header_tit.d thetest.o -L-lstdc++
 header_tit.o: In function `_Dmain':
 header_tit.d:(.text+0x20): undefined reference to `_D7thetest7TheTest7__ClassZ'
 header_tit.d:(.text+0x2f): undefined reference to
`_D7thetest7TheTest5_ctorMUiZC7thetest7TheTest'
 collect2: ld returned 1 exit status
 ----------------------------------------------------------------------------------------
Jul 29 2008