Linking D library to C++ code
Asked Answered
S

1

6

Recently I learned the beautiful language D, which is so more plastic and helps yourself writing stable fast programs. But its not popular... because few code written on D and so more on C and C++. Therefore after I read the book of Andrei Alexanderscu where author very superficially described question about linking of D library to C++ code, I tried learn it myself and written some code on D where defined function that returns an instance of CompleteAutomata class which implements AutomataInterface defined also in C++ code:

#ifndef AUTOMATAINTERFACE_H
#define AUTOMATAINTERFACE_H

class AutomataInterface {
public:
    virtual ~AutomataInterface() {}

    virtual void next() = 0;

    virtual void save() = 0;
    virtual void restore() = 0;
    virtual void zerofile() = 0;

    virtual void invert(unsigned long x, unsigned long y) = 0;

    virtual int state(unsigned long x, unsigned long y) const = 0;

    virtual unsigned long x() const = 0;
    virtual unsigned long y() const = 0;
};

AutomataInterface *createAutomata(unsigned long x, unsigned long y);

#endif // AUTOMATAINTERFACE_H

Relevant D code:

import agregator; // this is my own lib

extern(C++) {
    interface AutomataInterface {
        void next();

        void save();
        void restore();
        void zerofile();

        void invert(size_t x, size_t y);

        int state(size_t x, size_t y) const;

        size_t x() const;
        size_t y() const;
    }

    AutomataInterface createAutomata(ulong x, ulong y) {
        return new CompleteAutomata(x, y);
    }
}

export class CompleteAutomata : AutomataInterface {
    // instance variables...
    this(size_t x, size_t y) { /* ... */ }

    extern(C++) {
        override void next() {
            // ...
        }

        // others overridden interface methods...
    }
}

After code had written, I've compiling of D library by two different compilers (dmd and gdc), with following flags:

dmd -release -O -lib -odlib -ofliblife.h *.d

or

gdc -frelease -O2 -Wall -c *.d
ar cq lib/liblife.a *.o

When I trying link each of received libs to Qt project by adding path to library dir (-L option) and adding a lib directly (-l option). I got errors of in both cases.

In first dmd case I have "undefined reference to `_d_newclass'" and couple of another errors:

g++ -Wl,-O1 -Wl,-z,relro -o automata main.o mainwindow.o renderarea.o button.o playbutton.o moc_mainwindow.o moc_renderarea.o moc_button.o moc_playbutton.o -L/home/newmen/projects/d/life/lib -llife -lQtGui -lQtCore -lpthread 
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1fe_5b0.o): In function `createAutomata(unsigned int, unsigned int)':
complete_automata.d:(.text._Z14createAutomatajj+0x27): undefined reference to `_d_newclass'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.data+0x0): undefined reference to `_D14TypeInfo_Class6__vtblZ'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.data+0x50): undefined reference to `_D6Object7__ClassZ'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.data+0xd0): undefined reference to `_D14TypeInfo_Class6__vtblZ'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.data+0x120): undefined reference to `_D6Object7__ClassZ'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.rodata+0x68): undefined reference to `_D6object6Object8toStringMFZAya'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.rodata+0x70): undefined reference to `_D6object6Object6toHashMFNbNeZm'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.rodata+0x78): undefined reference to `_D6object6Object5opCmpMFC6ObjectZi'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.rodata+0x80): undefined reference to `_D6object6Object8opEqualsMFC6ObjectZb'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.rodata+0xf8): undefined reference to `_D6object6Object8toStringMFZAya'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.rodata+0x100): undefined reference to `_D6object6Object6toHashMFNbNeZm'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.rodata+0x108): undefined reference to `_D6object6Object5opCmpMFC6ObjectZi'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.rodata+0x110): undefined reference to `_D6object6Object8opEqualsMFC6ObjectZb'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o): In function `_D17complete_automata16CompleteAutomata6__ctorMFmmZC17complete_automata16CompleteAutomata':
complete_automata.d:(.text._D17complete_automata16CompleteAutomata6__ctorMFmmZC17complete_automata16CompleteAutomata+0x1f): undefined reference to `_d_newclass'
complete_automata.d:(.text._D17complete_automata16CompleteAutomata6__ctorMFmmZC17complete_automata16CompleteAutomata+0x46): undefined reference to `_d_newclass'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o): In function `CompleteAutomata::next()':
complete_automata.d:(.text._ZN16CompleteAutomata4nextEv+0x2f): undefined reference to `_d_newclass'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o): In function `CompleteAutomata::save()':
complete_automata.d:(.text._ZN16CompleteAutomata4saveEv+0x25): undefined reference to `_adDupT'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o): In function `CompleteAutomata::restore()':
complete_automata.d:(.text._ZN16CompleteAutomata7restoreEv+0x33): undefined reference to `_d_newclass'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o): In function `CompleteAutomata::zerofile()':
complete_automata.d:(.text._ZN16CompleteAutomata8zerofileEv+0x2f): undefined reference to `_d_newclass'
/home/newmen/projects/d/life/lib/liblife.a(object_201_8b7.o): In function `no symbol':
/usr/include/dmd/druntime/import/object.di:(.text+0x6): undefined reference to `_Dmodule_ref'
/home/newmen/projects/d/life/lib/liblife.a(object_201_8b7.o):(.data._D12TypeInfo_Axi6__initZ+0x0): undefined reference to `_D14TypeInfo_Array6__vtblZ'
/home/newmen/projects/d/life/lib/liblife.a(object_201_8b7.o): In function `_D46/usr/include/dmd/druntime/import/object.di.5137__arrayZ':
/usr/include/dmd/druntime/import/object.di:(.text._D46/usr/include/dmd/druntime/import/object.di.5137__arrayZ+0x16): undefined reference to `_d_array_bounds'
/home/newmen/projects/d/life/lib/liblife.a(object_201_8b7.o): In function `_D46/usr/include/dmd/druntime/import/object.di.5138__assertFiZv':
/usr/include/dmd/druntime/import/object.di:(.text._D46/usr/include/dmd/druntime/import/object.di.5138__assertFiZv+0x16): undefined reference to `_d_assertm'
/home/newmen/projects/d/life/lib/liblife.a(object_201_8b7.o): In function `_D46/usr/include/dmd/druntime/import/object.di.51315__unittest_failFiZv':
/usr/include/dmd/druntime/import/object.di:(.text._D46/usr/include/dmd/druntime/import/object.di.51315__unittest_failFiZv+0x16): undefined reference to `_d_unittestm'
/home/newmen/projects/d/life/lib/liblife.a(object_203_875.o): In function `no symbol':
/usr/include/dmd/druntime/import/object.di:(.text+0x6): undefined reference to `_Dmodule_ref'
/home/newmen/projects/d/life/lib/liblife.a(object_203_875.o):(.data._D11TypeInfo_xi6__initZ+0x0): undefined reference to `_D14TypeInfo_Const6__vtblZ'
/home/newmen/projects/d/life/lib/liblife.a(object_203_875.o):(.data._D11TypeInfo_xi6__initZ+0x10): undefined reference to `_D10TypeInfo_i6__initZ'
/home/newmen/projects/d/life/lib/liblife.a(object_203_875.o): In function `_D46/usr/include/dmd/druntime/import/object.di.5157__arrayZ':
/usr/include/dmd/druntime/import/object.di:(.text._D46/usr/include/dmd/druntime/import/object.di.5157__arrayZ+0x16): undefined reference to `_d_array_bounds'
/home/newmen/projects/d/life/lib/liblife.a(object_203_875.o): In function `_D46/usr/include/dmd/druntime/import/object.di.5158__assertFiZv':
/usr/include/dmd/druntime/import/object.di:(.text._D46/usr/include/dmd/druntime/import/object.di.5158__assertFiZv+0x16): undefined reference to `_d_assertm'
/home/newmen/projects/d/life/lib/liblife.a(object_203_875.o): In function `_D46/usr/include/dmd/druntime/import/object.di.51515__unittest_failFiZv':
/usr/include/dmd/druntime/import/object.di:(.text._D46/usr/include/dmd/druntime/import/object.di.51515__unittest_failFiZv+0x16): undefined reference to `_d_unittestm'
/home/newmen/projects/d/life/lib/liblife.a(agregator.o): In function `no symbol':
agregator.d:(.text+0x6): undefined reference to `_Dmodule_ref'
/home/newmen/projects/d/life/lib/liblife.a(agregator.o):(.data+0x10): undefined reference to `_D3std6random12__ModuleInfoZ'
/home/newmen/projects/d/life/lib/liblife.a(agregator.o):(.rodata+0x20): undefined reference to `_D14TypeInfo_Class6__vtblZ'
/home/newmen/projects/d/life/lib/liblife.a(agregator.o): In function `_D9agregator7__arrayZ':
agregator.d:(.text._D9agregator7__arrayZ+0x16): undefined reference to `_d_array_bounds'
/home/newmen/projects/d/life/lib/liblife.a(agregator.o): In function `_D9agregator8__assertFiZv':
agregator.d:(.text._D9agregator8__assertFiZv+0x16): undefined reference to `_d_assertm'
/home/newmen/projects/d/life/lib/liblife.a(agregator.o): In function `_D9agregator15__unittest_failFiZv':
agregator.d:(.text._D9agregator15__unittest_failFiZv+0x16): undefined reference to `_d_unittestm'
/home/newmen/projects/d/life/lib/liblife.a(agregator_2_5fd.o):(.data+0x0): undefined reference to `_D14TypeInfo_Class6__vtblZ'
/home/newmen/projects/d/life/lib/liblife.a(agregator_2_5fd.o):(.data+0x50): undefined reference to `_D6Object7__ClassZ'
/home/newmen/projects/d/life/lib/liblife.a(agregator_2_5fd.o):(.rodata+0x48): undefined reference to `_D6object6Object8toStringMFZAya'
...

In second case (when using gdc) I receives message about "multiple definition of":

g++ -Wl,-O1 -Wl,-z,relro -o cellular_life main.o mainwindow.o renderarea.o button.o playbutton.o moc_mainwindow.o moc_renderarea.o moc_button.o moc_playbutton.o -L/home/newmen/projects/d/life/lib -llife -lQtGui -lQtCore -lpthread 
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o): In function `_D17complete_automata16CompleteAutomata7restoreMRZv14SliceAgregator9initValueMxFmmZi':
complete_automata.d:(.text+0x0): multiple definition of `_D17complete_automata16CompleteAutomata7restoreMRZv14SliceAgregator9initValueMxFmmZi'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):complete_automata.d:(.text._D17complete_automata16CompleteAutomata7restoreMRZv14SliceAgregator9initValueMxFmmZi+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o): In function `CompleteAutomata::invert(unsigned long long, unsigned long long)':
complete_automata.d:(.text+0x40): multiple definition of `CompleteAutomata::invert(unsigned long long, unsigned long long)'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):complete_automata.d:(.text._ZN16CompleteAutomata6invertEyy+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o): In function `CompleteAutomata::state(unsigned long long, unsigned long long) const':
complete_automata.d:(.text+0x60): multiple definition of `CompleteAutomata::state(unsigned long long, unsigned long long) const'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):complete_automata.d:(.text._ZNK16CompleteAutomata5stateEyy+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o): In function `CompleteAutomata::x() const':
complete_automata.d:(.text+0x80): multiple definition of `CompleteAutomata::x() const'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):complete_automata.d:(.text._ZNK16CompleteAutomata1xEv+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o): In function `CompleteAutomata::y() const':
complete_automata.d:(.text+0xa0): multiple definition of `CompleteAutomata::y() const'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):complete_automata.d:(.text._ZNK16CompleteAutomata1yEv+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o): In function `CompleteAutomata::next()':
complete_automata.d:(.text+0x140): multiple definition of `CompleteAutomata::next()'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):complete_automata.d:(.text._ZN16CompleteAutomata4nextEv+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o):(.tbss+0x10): multiple definition of `_D17complete_automata16CompleteAutomata4nextMRZv7changerC7changer7Changer'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.tbss+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o): In function `CompleteAutomata::restore()':
complete_automata.d:(.text+0x1b0): multiple definition of `CompleteAutomata::restore()'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):complete_automata.d:(.text._ZN16CompleteAutomata7restoreEv+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o):(.tbss+0x8): multiple definition of `_D17complete_automata16CompleteAutomata7restoreMRZv9agregatorC9agregator9Agregator'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.tbss+0x8): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o):(.data+0x180): multiple definition of `_D_ZN16CompleteAutomata7restoreEv14SliceAgregator7__ClassZ'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.data+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o): In function `CompleteAutomata::zerofile()':
complete_automata.d:(.text+0x220): multiple definition of `CompleteAutomata::zerofile()'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):complete_automata.d:(.text._ZN16CompleteAutomata8zerofileEv+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o):(.tbss+0x0): multiple definition of `_D17complete_automata16CompleteAutomata8zerofileMRZv9agregatorC9agregator9Agregator'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.tbss+0x10): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o): In function `CompleteAutomata::save()':
complete_automata.d:(.text+0x290): multiple definition of `CompleteAutomata::save()'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):complete_automata.d:(.text._ZN16CompleteAutomata4saveEv+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o):(.data+0x80): multiple definition of `_D17complete_automata16CompleteAutomata7__ClassZ'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.data+0xd0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o): In function `_D17complete_automata16CompleteAutomata6__ctorMFmmZC17complete_automata16CompleteAutomata':
complete_automata.d:(.text+0x9b0): multiple definition of `_D17complete_automata16CompleteAutomata6__ctorMFmmZC17complete_automata16CompleteAutomata'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):complete_automata.d:(.text._D17complete_automata16CompleteAutomata6__ctorMFmmZC17complete_automata16CompleteAutomata+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o):(.rodata+0x420): multiple definition of `_D17complete_automata16CompleteAutomata6__vtblZ'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.rodata+0xf0): first defined here
/usr/bin/ld: Warning: size of symbol `_D17complete_automata16CompleteAutomata6__vtblZ' changed from 104 in /home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o) to 112 in /home/newmen/projects/d/life/lib/liblife.a(complete_automata.o)
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o):(.rodata+0x4a0): multiple definition of `_D17complete_automata16CompleteAutomata6__initZ'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.rodata+0x90): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o):(.rodata+0x4e0): multiple definition of `_D_ZN16CompleteAutomata7restoreEv14SliceAgregator6__vtblZ'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.rodata+0x60): first defined here
/usr/bin/ld: Warning: size of symbol `_D_ZN16CompleteAutomata7restoreEv14SliceAgregator6__vtblZ' changed from 48 in /home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o) to 56 in /home/newmen/projects/d/life/lib/liblife.a(complete_automata.o)
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o):(.rodata+0x520): multiple definition of `_D_ZN16CompleteAutomata7restoreEv14SliceAgregator6__initZ'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1ff_675.o):(.rodata+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(agregator.o): In function `_D3std7complex14__T7ComplexTeZ7Complex8toStringMxFMDFAxaZvAyaZAya12__lambda1223MFNbNfAxaZv':
agregator.d:(.text+0xaf): undefined reference to `_D11TypeInfo_Aa6__initZ'
agregator.d:(.text+0xb7): undefined reference to `_d_arrayappendT'
/home/newmen/projects/d/life/lib/liblife.a(agregator.o): In function `_D3std4conv16__T6toImplTiTxkZ6toImplFNaNfxkZi15__dgliteral1389MFNaNfZC6object9Throwable':
agregator.d:(.text+0xc5): undefined reference to `_D3std4conv21ConvOverflowException7__ClassZ'
agregator.d:(.text+0xca): undefined reference to `_d_newclass'
agregator.d:(.text+0xed): undefined reference to `_D3std4conv21ConvOverflowException6__ctorMFAyaAyamZC3std4conv21ConvOverflowException'
/home/newmen/projects/d/life/lib/liblife.a(agregator.o): In function `_D3std6format17__T9getNthIntTxeZ9getNthIntFNaNfkxeZi.part.6':
agregator.d:(.text+0x105): undefined reference to `_D3std6format15FormatException7__ClassZ'
agregator.d:(.text+0x10a): undefined reference to `_d_newclass'
...

After two days of attempts to do so...

Recently I've try add Phobos (D standard library) to linking process. For dmd -lphobos2 flag and for gdc -lgphobos2 flag correspond. But it not help me...

When using dmd linker output:

g++ -Wl,-O1 -Wl,-z,relro -o cellular_life main.o mainwindow.o renderarea.o button.o playbutton.o moc_mainwindow.o moc_renderarea.o moc_button.o moc_playbutton.o -L/home/newmen/projects/d/life/lib -llife -lQtGui -lQtCore -lpthread -lphobos2
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libphobos2.so: undefined reference to `curl_easy_duphandle@CURL_GNUTLS_3'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libphobos2.so: undefined reference to `curl_easy_strerror@CURL_GNUTLS_3'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libphobos2.so: undefined reference to `curl_slist_free_all@CURL_GNUTLS_3'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libphobos2.so: undefined reference to `curl_global_init@CURL_GNUTLS_3'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libphobos2.so: undefined reference to `curl_easy_perform@CURL_GNUTLS_3'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libphobos2.so: undefined reference to `curl_easy_init@CURL_GNUTLS_3'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libphobos2.so: undefined reference to `curl_easy_pause@CURL_GNUTLS_3'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libphobos2.so: undefined reference to `_Dmain'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libphobos2.so: undefined reference to `curl_easy_setopt@CURL_GNUTLS_3'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libphobos2.so: undefined reference to `curl_slist_append@CURL_GNUTLS_3'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libphobos2.so: undefined reference to `curl_global_cleanup@CURL_GNUTLS_3'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libphobos2.so: undefined reference to `curl_easy_cleanup@CURL_GNUTLS_3'
collect2: error: ld returned 1 exit status
make: *** [cellular_life] Error 1

and I've try substitute of libcurl-gnutls: ln -s /usr/lib64/libcurl.so.4 /usr/lib64/libcurl-gnutls.so.4. Then result of linking the same but without message about libcurl-gnutls.

When using gdc linker output again talk about "multiple definition to":

/home/newmen/gcc/bin/g++ -Wl,-O1 -Wl,-z,relro -o cellular_life main.o mainwindow.o renderarea.o button.o playbutton.o moc_mainwindow.o moc_renderarea.o moc_button.o moc_playbutton.o    -L/home/newmen/gcc/lib64 -L/home/newmen/projects/d/life/lib -llife -lQtGui -lQtCore -lpthread -lgphobos2
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o): In function `_D17complete_automata16CompleteAutomata7restoreMRZv14SliceAgregator9initValueMxFmmZi':
complete_automata.d:(.text+0x0): multiple definition of `_D17complete_automata16CompleteAutomata7restoreMRZv14SliceAgregator9initValueMxFmmZi'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1e3_675.o):complete_automata.d:(.text._D17complete_automata16CompleteAutomata7restoreMRZv14SliceAgregator9initValueMxFmmZi+0x0): first defined here
/home/newmen/projects/d/life/lib/liblife.a(complete_automata.o): In function `CompleteAutomata::invert(unsigned long long, unsigned long long)':
complete_automata.d:(.text+0x40): multiple definition of `CompleteAutomata::invert(unsigned long long, unsigned long long)'
/home/newmen/projects/d/life/lib/liblife.a(complete_automata_1e3_675.o):complete_automata.d:(.text._ZN16CompleteAutomata6invertEyy+0x0): first defined here
...
/home/newmen/gcc/lib64/libgphobos2.a(dmain2.o): In function `main':
/home/newmen/projects/distrib/gcc-4.8.1/x86_64-unknown-linux-gnu/libphobos/libdruntime/../../.././libphobos/libdruntime/rt/dmain2.d:394: multiple definition of `main'
main.o:/home/newmen/projects/d/life/qt_viewer/main.cpp:5: first defined here
/usr/bin/ld: /home/newmen/gcc/lib64/libgphobos2.a(time.o): undefined reference to symbol 'clock_getres@@GLIBC_2.2.5'
/usr/bin/ld: note: 'clock_getres@@GLIBC_2.2.5' is defined in DSO /lib64/librt.so.1 so try adding it to the linker command line
/lib64/librt.so.1: could not read symbols: Invalid operation
collect2: error: ld returned 1 exit status
make: *** [cellular_life] Error 1

with message about librt.so.1 at end. I inspect /usr/lib64 and seen there it library file.

Dear magic, please tell me how to connect the D library to C++ code.

Sometimes answered 14/7, 2013 at 13:15 Comment(0)
S
9

It is generally easier to let the D compiler do the linking:

 g++ -c yourfile.cpp
 dmd yourfile.o d_file.d

You might have to add curl to it as well, same as you did before. To pass a linker argument through dmd (or gdmd if you're using gdc, should work the same way), pass -Larg

 dmd yourfile.o d_file.d -L-lstdc++ -L-lcurl -L-lQtGui # and so on

It is generally easier to put main() in D too (it can just immediately call out to a C++ defined function too) because otherwise you'll probably have to initialize the D runtime before using it from C++.

But to finish the process you've started... first thing, looks like your liblife.a has the same file added twice. I'd try deleting that file and recreating it, or just skipping that step and passing the .o files to the linker directly without first packing them into a .a. That'll simplify things a bit.

My other question is: why is it trying to pull the D main? Is there a main() in your .d code somewhere? If so, that's ok, but you'll have to remove the one from your C++ code. (Perhaps rename it into cppmain and then call it from the D main:

D code:

extern(C++) int cppmain(int argc, char** argv);

int main() {
        import core.runtime;
        return cppmain(Runtime.cArgs.argc, Runtime.cArgs.argv);
}

And that will forward to your C++ main. If you want to remove the D main (assuming it is there, if not let me know and I'll try to think what else could cause that linker error), before tou use D code in C++, you'll want to initialize D. So:

D code:

extern(C++) void initD() {
      import core.runtime;
       Runtime.initialize();
}

C++ code:

extern "C++" void initD();
int main() {
      initD();
      // the rest of your stuff
 }

If you don't do that, calling D functions is liable to cause a segfault.

But to sum up, I'm pretty sure you have a duplicate .o file added to your archive, and main defined in both D and C++. Delete the duplicate in the archive and kill one of the duplicate mains and you should have some success.

Subtype answered 16/7, 2013 at 13:22 Comment(8)
Before I see your answer, I find out that as a linker need to use dmd. I've tried to link code when the main function described in the C++ code. Under such case, I got the binary and when start it got segfault, which you warn. Now, after reading your post I tried to create a main function in D code and call from it cppmain function, as you wrote. In such a case, after linking I also get the binary, which is also when start getting a segfault, but this time backtrace much more plentiful, and it indicates that an error occurs at the time of referral to the methods of a D class CompleteAutomataSometimes
One common mistake when coming to D from C++ is that D classes always need to be heap allocated, so make sure you're doing: CompleteAutomata a = new CompleteAtomata();, and not just CompleteAutomata a;. The reason is classes in D are always done by reference (MyClass a in D is most like MyClass* a in C++), so if you don't initialize it with new, the reference will be null and segfault when you use it.Subtype
another note, D classes should be new'd from D, and C++ classes should be constructed in C++. There is a way around this, but the languages don't know how to call each other's constructors, so you'd have to do it manually to initialize the object. It is a lot easier to just new it in their native language though.Subtype
I use createAutomata function for create an CompleteAutomata object as I described in my post (by new). It is declared in C++ and implemented in D. This function called in C++ code, and the result is assigned to a pointer to AutomataInterface. Further, trying to call methods of a class through this pointer is leads to setfault.Sometimes
I tried to save the result of memory allocation (creation of CompleteAutomata object) into a variable in D code, and then return this instance from createAutomata function. But my attempt to nothing lead.Sometimes
I downloaded your code and was able to get it to link and run too. If you weren't able to link still, let me know and I'll write that up too. But I found two problems in your C++ code: 1) automatainterface.h listed a virtual destructor - that shouldn't be there, so just comment it out. That's what was causing the segfaults, C++ and D didn't agree on the number of virtual functions so everything was off by one. The second mistake is in ~RenderArea, you "delete _cellular" - don't do that because it was created in D, so the D garbage collector managed it. Manually deleting will cause double free.Subtype
I'm repair all mistakes whats about you wrote, and... It's work!! Awesome much more thanks.Sometimes
That was for me the final + for the D language. Just a few lines in the D code and done, I can reuse a lot of C++ code.Allege

© 2022 - 2024 — McMap. All rights reserved.