Templates in C möglich machen?



  • Testo schrieb:

    Naja...weil CODE_OTHER eben von jedem runterladbar ist und standardmässig einen c-compiler drin hat.

    ich bezweifle dass der Code einen eingebauten COmpiler hat 😉

    Ich würde gerne denjenigen dann anbieten meine integration zu nutzen will ihnen aber nicht aufzwingen auch ihre makefiles umzuschreiben....
    oder wäre das gar kein aufwand?

    wenn die Makefiles ordentlich gemacht wurden steht da an einer Stelle drin wie der Compiler aufzurufen ist. Das wäre also eine Zeile zu ändern.



  • puh...also erstmal danke für eure zahlreichen antworten.
    Ich bin mir nicht sicher ob ich euch verstehe. Vielleicht könnte ich mal ein Minimalbeispiel aufsetzen:

    Hier mal meine main.c

    /*
     * This is my C-Program
     * */
    
    #include "stdlib.h"
    
    int main()
    {
            double * mydata = NULL; 
            /* Here i want to use the MyB.foo(MyC<double>* myC) but 
             * i dont have any myC object because i cannot create it
             * here because its template based*/
            /* ?????????? */
            MyC<double>* mtx = new MyC<double>();
    }
    

    Und hier mein main.cpp

    // This is my C++ Programm
    #include <iostream>
    #include <string.h>
    
    template<class T> class MyC
    {
        public:
            MyC<T>() {
                    data = NULL;
                    memset(data, 0, 10*sizeof(T));
            }
    
            ~MyC<T>() { delete [] data; }
            T* data;
    };
    
    template<class T> class MyB
    {
            public:
                    MyB<T>() {
                            mydata = NULL;
                    }
    
                    void foo(MyC<T>* mtx) {
                            memcpy(mtx->data,mydata,10*sizeof(T));
                    }
                    T* mydata;
    };
    
    int main()
    {
            MyC<int>* mtx = new MyC<int>();
    
            MyB<int>* myB = new MyB<int>();
    
            myB->foo(mtx);
    
            delete mtx;
            delete myB;
    }
    

    Das main.c programm ist CODE_OTHER und main.cpp ist CODE_MY. Mein Problem ist ich habe in CODE_MY eigene datenstrukturen die templatebasiert sind. Wenn in CODE_OTHER jetzt wieder andere datenstrukturen sind muss ich ja irgendwie ein mapping machen oder? Ich meine ich muss doch dann CODE_MY ein wenig abändern weil ich ja ganz andere datenstrukturen einspeisen werde...
    oder soll ich jetzt für jede template-klasse einen wrapper schreiben?



  • oder anders ausgedrückt in worten:

    CODE_OTHER hat eine stuktur *data z.B.

    in CODE_MY steht dann

    int main()
    {
        MyC<T>* mtx = NULL;
        mtx = readMatrix();
        Algorithm(mtx);
    }
    

    Wie schaffe ich es Algorithm statt auf mtx auf *data laufen zu lassen?

    Ich muss doch dazu in CODE_MY eine funktion schreiben die *data entgegennimmt und die umwandlung macht? und dann ncoh eine zusätzliche funktion um Algorithm aufzurufen. Aber dazu musss ich ja die main() in CODE_MY verändern oder nicht?



  • Und nochmal code :

    Hier mal CODE_MY wo ich eben templatebasiert bin.

    // This is my C++ Programm
    #include <iostream>
    #include <string.h>
    template<class T> class MyC
    {
        public:
            MyC<T>() {
                    data = new T[10];
                    memset(data, 0, 10*sizeof(T));
            }
            ~MyC<T>() { delete [] data; }
            void print(MyC<int>* mtx);
            T* data;
    };
    template <> void
    MyC<int>::print(MyC<int>* mtx)
    {
       // Hier z.B. mtx ausgeben oder andere
       // Dinge mit mtx tun...
         for (int i = 0; i <10; i++)
            std::cout << i << std::endl;
    }
    template<class T> class MyB
    {
            public:
                    MyB<T>() {
                            mydata = new T[10];
                    }
    
                    void Algorithm(MyC<T>* mtx) {
                            // do something with mtx
                            mtx->print(mtx);
                            memcpy(mtx->data,mydata,10*sizeof(T));
                    }
                    T* mydata;
    };
    int main()
    {
            MyC<int>* mtx = new MyC<int>();
            MyB<int>().Algorithm(mtx);
            delete mtx;
    }
    

    Hier mal das C programm CODE_OTHER welches eben z.B. die data struktur hat.

    /*
     * This is my C-Program
     * */
    
    #include "stdlib.h"
    
    int main()
    {
            double* data = calloc(10, sizeof(double));
    
            free(mydata);
    }
    

    Und wie schaffe ich es jetzt eine verbindung zwischen beiden herzustellen.
    Also data über
    MyC<int>::print(MyC<int>
    mtx)
    auszugeben?



  • Puh....
    seh ich das richtig dass ich diesen code via c++-compiler übersetze:

    //foo.hpp, das C++-Template
    
    template <class T>
    class Foo
    {
    public:
      Foo f(T const& i) : i(i) {}
      int bar() {return i;}
    private:
      T i;
    };
    
    //foowrap.h, C/C++-Header
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    #define FOOWRAP(type)                          \
                                                   \
    typedef struct { void* ptr; } FOO_##type;      \
                                                   \
    FOO_##type create_foo_##type( const type* pi); \
    type call_bar_foo_##type(FOO_##type foo);      \
    void destroy_foo_##type(FOO_##type foo)
    
    FOOWRAP(int);
    FOOWRAP(short);
    FOOWRAP(float);
    #undef FOOWRAP
    
    #ifdef __cplusplus
    } /*end extern "C"*/
    #endif
    
    //foowrap.cpp - implementierung auf C++-Seite
    #include "foowrap.h"
    #include "foo.hpp"
    
    #define FOOWRAPIMPL(type)                      \
                                                   \
    FOO_##type create_foo_##type( const type* pi)  \
    {                                              \
      FOO_##type t;                                \
    /*hiermit wird das temlate auch instantiiert:*/\
      t.ptr = new Foo<type>(*pi);                  \
      return t;                                    \
    }                                              \
                                                   \
    type call_bar_foo_##type(FOO_##type foo)       \
    {                                              \
      Foo<type>* pf                                \
        = static_cast<Foo<type>*>(foo.ptr);        \
      return pf->bar();                            \
    }                                              \
                                                   \
    void destroy_foo_##type(FOO_##type foo)        \
    {                                              \
      Foo<type>* pf                                \
        = static_cast<Foo<type>*>(foo.ptr);        \
      delete pf; pf = NULL;                        \
    }                                              
    
    FOOWRAPIMPL(int);
    FOOWRAPIMPL(float);
    FOOWRAPIMPL(short);
    
    #undef FOOWRAPIMPL
    

    und diesen code nur mit c - wie sieht dann aber das linking aus??

    //main.c - C-Datei!
    #include "foowrap.h"
    int main()
    {
      FOO_int fi = create_foo_int(14);
      int i = call_bar_foo_int(fi);
      printf("Foos i: %d\n", i);
      destroy_foo_int(fi);
    }
    


  • Freund Testo, dir ist schon klar dass es in C auch keine Klassen gibt, ja?
    Was du willst hat erstmal mit Templates nichts zu tun, sondern damit, dass es eben in C keine Klassen gibt.
    Ob es sich dabei C++ seitig um Templates handelt oder um "normale" Klassen, ist C seitig komplett egal.



  • Danke erneut.

    @hustbaer. Ja du hast recht - ich sehe jetzt mein Problem etwas klarer.
    Das Beispiel von pumuckl ist ein wenig "zu schwer" für mich im Moment.
    Ich würde mich freuen wenn mir jemand mit meinem minimalbeispiel weiterhelfen könnte - in diesem möchte ich den c++ code in dem c-code verwenden. Ich hoffe sehr dass ich ein korrektes minimalbeispiel aufzeige dass mein problem beschreibt. Ich bin über andere Hilfe jedesmal dankbar....:

    Der C++ code

    // This is my C++ Programm
    #include <iostream>
    #include <string.h>
    
    template<class T> class MyC
    {
        public:
    	MyC<T>() { 
    		data = new T[10];
    		memset(data, 0.0, 10*sizeof(T));
    	}
    	~MyC<T>() { delete [] data; }
    	void print(MyC<int>* mtx);
    	T* data;
    };
    
    template <> void
    MyC<int>::print(MyC<int>* mtx)
    {
       // Hier z.B. mtx ausgeben oder andere
       // Dinge mit mtx tun...
         int a;
         for (int i = 0; i <10; i++)
         	std::cout << mtx->data[i] << std::endl;
    }
    
    template<class T> class MyB
    {
    	public:
    		MyB<T>() {
    			mydata = new T[10];
    		}
            // do something with mtx
    		void Algorithm(MyC<T>*& mtx) {
                for (int i= 0; i < 10; i++)
                    mtx->data[i] = i;
    
                mtx->print(mtx);
    			memcpy(mtx->data,mydata,10*sizeof(T));
    		}
    		T* mydata;
    };
    
    int main()
    {
    	MyC<int>* mtx = new MyC<int>();
    	MyB<int>().Algorithm(mtx);
    	delete mtx;
    }
    

    Der C - Code

    /*
     * This is my C-Program
     * */
    
    #include "stdlib.h"
    
    int main()
    {
    	int* data = calloc(10, sizeof(int));
    
        for (int i = 10; i > 0; i--)
            data[10-i] = i;
    
        // Hier würde ich gern data über die C++ Klasse
        // so ändern dass in data in aufsteigender 
        // art die i's gespeichert sind.
    
        for (int i = 0; i < 10; i++)
            printf("data[%d] = %d\n", i, data[i]);
    
    	free(data);
    }
    


  • Die erste Sache ist schonmal: entscheide dich in welchem Codeteil die main() überhaupt sein soll. Schreib mal deinen Code komplett so wie du ihn schreiben würdest wenn du in C die Teplates benutzen könntest. Was du da hast, nämlich zwei main()-Funktionen ist sinnfrei und machts extrem schwer zu erkennen was du eigentlich willst.



  • Entschuldigung. Ich möchte die main von C benutzen also main.c.
    Also main soll im letzteren code-teil sein.

    Ich versuche mal (wie vorgeschlagen) den code so zu schreiben wie wenn ich die templates in c verwenden könnte:

    /*
     * This is my C-Program
     * */
    
    #include "stdlib.h"
    
    int main()
    {
        int* data = calloc(10, sizeof(int));
    
        for (int i = 10; i > 0; i--)
            data[10-i] = i;
    
        // Hier würde ich gern data über die C++ Klasse
        // so ändern dass in data in aufsteigender 
        // art die i's gespeichert sind.
    
        // Ich habe schwierigkeiten mich richtig auszudrücken:
        // Ich habe hier in meinem C-code eine struktur data
        // (vereinfacht ein array) die eben anders ist als
        // Objekte vom Typ MyC. Ich möchte aber über Algorithm
        // mein hieriges data so ändern wie wenn ich MyB.Algorithm()
        // aufrufen würde. Dazu brauche ich wohl erstmal sowas wie
        // eine methode die mir mein data in ein MyC Objekt verändert
        // oder? ALso so ein Mapping zwischen den Datenstrukturen.
        //
        // Im Prinzip sind es zwei dinge die ich nicht ganz verstehe.
        // 1. Wie verbinde ich beide codes so das ich aus c die c++
        // sachen aufrufen kann. das wäre dann so ein aufruf wie:
        MyC<int> * mtx = new MyC<int>();
        MyB<int>().Algorithm(mtx);
    
        // UND 2. habe ich hier in meinem c-programm ja andere datenstrukturen
        // (hier ist es jetzt nur vereinfacht ein array aber es könnte
        // ja auch eine komplexe structure sein). Und hier verstehe ich 
        // eben auch nicht wie ich denn ausgehend von meinen hierigen
        // datenstrukturen (data) den c++ code nutzen könnte also so in 
        // etwa:
        MyC<int>* mtx = convert_data_to_MyC(data);
        MyB<int>().Algorithm(mtx);
        *data = convert_MyC_to_data(mtx);
    
        // Es wäre sehr schön wenn letzteres gehen würde. Im Prinzip
        // sollte dann ja die folgende ausgabe wieder aufsteigende 
        // i's ausgeben innerhalb data.  
    
        for (int i = 0; i < 10; i++)
            printf("data[%d] = %d\n", i, data[i]);
    
        free(data);
    }
    


  • dann mal (beispielsweise) hier den Code, wie du ihn schreiben könntest:

    //main.c
    #include "myc_wrapper.h"
    #include "myb_wrapper.h"
    
    int main()
    {
        /*...*/
        //MyC<int> * mtx = new MyC<int>();
        WrapMyC_int mtx = myc_int_create(); //konstruktor
    
        //MyB<int>().Algorithm(mtx);        
        WrapMyB_int tmp = myb_int_create(); //konstruktor
        myb_int_algorithm(tmp, mtx);        //methode
    
        myc_int_delete(mtx);                //destruktor
        myb_int_delete(tmp);                //destruktor
    
        /*...*/
        //MyC<int>* mtx = convert_data_to_MyC(data);
        WrapMyC_int mtx = myc_int_create_1(data); //anderer konstruktor
    
        //MyB<int>().Algorithm(mtx);
        WrapMyB_int tmp = myb_int_create(); //konstruktor
        myb_int_algorithm(tmp, mtx);        //methode
        myc_int_writetobuffer(mtx, data);   
    
        myc_int_delete(mtx);                //destruktor
        myb_int_delete(tmp);                //destruktor
    }
    

    C/C++-Header, ich hab mal beide zusammengeschmissen:

    //myc_wrapper.h, myb_wrapper.h
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    typedef struct WrapMyB_int_
    { 
      void* ptr;
    } WrapMyB_int;
    
    typedef struct WrapMyC_int_
    { 
      void* ptr;
    } WrapMyC_int;
    
    WrapMyB_int myb_int_create(void);
    void myb_int_algorithm(WrapMyB_int this_, WrapMyC_int arg);
    void myb_int_delete(WrapMyB_int this_); 
    
    WrapMyC_int myc_int_create(void);
    WrapMyC_int myc_int_create_1(int* data);
    void myc_int_writetobuffer(WrapMyC_int this_, int* buffer);
    void myc_int_delete(WrapMyC_int this_); 
    
    #ifdef __cplusplus
    } /*end extern "C"*/
    #endif
    

    C++-Definition:

    #include "myc_wrapper.h"
    #include "myb_wrapper.h"
    #include "myc.hpp" //MyC<T>
    #include "myb.hpp" //MyB<T>
    
    WrapMyB_int myb_int_create(void)
    {
      WrapMyB_int tmp;
      tmp.ptr = new MyB<int>();
      return tmp;
    }
    void myb_int_algorithm(WrapMyB_int this_, WrapMyC_int arg)
    {
      MyB<int>* mb = static_cast<MyB<int>*> this_.ptr;
      mb->Algorithm(arg);
    }
    void myb_int_delete(WrapMyB_int this_)
    {
      MyB<int>* mb = static_cast<MyB<int>*> this_.ptr;
      delete mb;
      this_.ptr = NULL;
    }
    
    //der Rest sei dir zur Übung überlassen ;)
    WrapMyC_int myc_int_create(void)
    {
      /* ... */
    }
    WrapMyC_int myc_int_create_1(int* data)
    {
      /* ... */
    }
    void myc_int_writetobuffer(WrapMyC_int this_, int* buffer)
    {
      /* ... */
    }
    void myc_int_delete(WrapMyC_int this_)
    {
      /* ... */
    }
    

    Der Clou ist: du kanns in C keine Klassen oder Poitner darauf rumreichen, weil C nicht weiß was das ist. Du reichst stattdessen einen voidpointer rum und nur der C++-Code weiß dass er das Ding auf eine Klasse umcasten kann und wie der zu benutzen ist.
    Aus jedem Konstruktor machst du eine Funktion, die ein entsprechendes wrapper-struct zurückliefert.
    Aus allen anderen Methoden inklusive Destruktoren machst du Funktionen, die die gleichen Rückgabewerte haben und zusätzlich zu den normalen Parametern noch das Wrapperstruct als this-Parameter übernehmen.

    Da Templates keine Klassen sind sondern nur ihre Instantiierungen Klassen sind, musst du das Ganze für jede Template-Instantiierung machen, die du vom C-Code aus benutzen willst. Oben habe ich das bei MyC und MyB jeweils nur für int gemacht.
    Da das immer wieder das selbe ist, hab ich in meinem ersten Beispiel ein langes Makro draus gemacht, das mir die Funktionsdeklarationen udn -definitionen jeweils für int, short und float generiert hat.



  • Wobei mir immer noch schleierhaft ist, WARUM du das machst.
    Sobald du in der main von CODE_OTHER rumfummelst, ist das nicht mehr das, was jeder User runterlädt.
    Andererseits hast du auch ne main in CODE_MY, den du ohne weiteres auch mit C-Code füttern kannst und vor allem abändern.

    Was ist eigentlich der Hintergrund, dass du dich genötigt siehst fremden Code in C zu verwenden und zu ändern, nur damit du deinen eigenen C++-Code einfügen kannst?



  • Was ist eigentlich der Hintergrund, dass du dich genötigt siehst fremden Code in C zu verwenden und zu ändern, nur damit du deinen eigenen C++-Code einfügen kannst?

    Naja: Wenn ich meinen Code nutzbar machen will in CODE_OTHER geht das doch nicht anders. Ich will dass die algorithmen innerhalb CODE_OTHER auf CODE_MY zurückgreifen können. Wäre das so nicht der richtige weg?

    @ Pumuckl:
    Herzlichen Dank für das Beispiel. Mir wird vieles klarer. Ich versuche gerade das Beispiel zu kompilieren. Sehe ich das richtig dass ich aus dem C++ code erstmal eine library (static) erstellen muss. Ich mache das unter linux im moment so:

    ar rcs libmaincpp.a MyB.o MyC.o
    

    Anschließend gehe ich zu dem "neuen" C-code der dne c++ code nutzen. Sehe ich das richtig dass ich hier dann gegn die library linken muss:

    gcc -o mainnew mainnew.c -L lmaincpp.a
    

    oder so ählnich?

    Aufgrund der undefined refeerences vermute ich dass beim linken etwas faul wird...



  • Ich bin weiterhin verwirrt wie ich eine LIbrary erstellen soll die nur aus headern besteht !? Bei der benutzung von templates kann ich doch nur header erstellen...ich habe keine *.cpp file für MyC.h ?



  • Testo schrieb:

    Ich bin weiterhin verwirrt wie ich eine LIbrary erstellen soll die nur aus headern besteht !? Bei der benutzung von templates kann ich doch nur header erstellen...ich habe keine *.cpp file für MyC.h ?

    Dann hast du pumuckl & Co nicht verstanden.

    Du musst für deinen C++ Code einen Wrapper schreiben, und dort musst du die Templates auch auf konkrete Typen festlegen. Anders geht es nicht.



  • 😞 Jetzt versteh ich nur noch Bahnhof.
    Ich dachte den wrapper hat pumuckl mir schon geschrieben. Da sind doch die cpp wrapper oder nicht? MIr istklar dass ich da in den leeren wappern noch was füllen muss...sehe ihc das falsch?



  • Testo schrieb:

    😞 Jetzt versteh ich nur noch Bahnhof.
    Ich dachte den wrapper hat pumuckl mir schon geschrieben. Da sind doch die cpp wrapper oder nicht? MIr istklar dass ich da in den leeren wappern noch was füllen muss...sehe ihc das falsch?

    Also ich sehe in seinem Wrapper durchaus cpp-Dateien. Und eben diese bilden deine Schnittstelle für C (Sprich: Sind Teil der C++ Bibliothek, und nicht etwa des C-Programmes).



  • Es tut mir echt leid aber ich schaffe es aus eigener Kraft nicht.
    Ich beschreibe es nochmal was ich tue:

    Ich habe C++ code:
    // MyC.h

    #ifndef MyC_
    #define MyC_
    
    #include <iostream>
    
    template<class T> class MyC
    {
        public:
        MyC<T>() { 
            data = new T[10];
            memset(data, 0, 10*sizeof(T));
        }
        ~MyC<T>() { delete [] data; }
        void print(MyC<int>* mtx);
        T* data;
    };
    
    template <> void
    MyC<int>::print(MyC<int>* mtx)
    {
       // Hier z.B. mtx ausgeben oder andere
       // Dinge mit mtx tun...
         int a;
         for (int i = 0; i <10; i++)
            std::cout << mtx->data[i] << std::endl;
    }
    
    #endif
    

    //MyB.h

    #ifndef MyB_
    #define MyB_
    
    #include "MyC.h"
    
    template<class T> class MyB
    {
        public:
            MyB<T>() {
                mydata = new T[10];
            }
            // do something with mtx
            void Algorithm(MyC<T>*& mtx) {
                for (int i= 0; i < 10; i++)
                    mtx->data[i] = i;
    
                mtx->print(mtx);
                memcpy(mtx->data,mydata,10*sizeof(T));
            }
            T* mydata;
    };
    
    #endif
    

    Und so wie ich es vertanden habe brauche ich für diese Klassen jetz wrapper:
    Also cpp-wrapper:
    // myb_wrapper.h

    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
        typedef struct WrapMyB_int_
        {
            void* ptr;
        } WrapMyB_int;
    
        WrapMyB_int myb_int_create(void);
        void myb_int_algorithm(WrapMyB_int this_, WrapMyC_int arg);
        void myb_int_delete(WrapMyB_int this_);
    
    #ifdef __cplusplus
    } /*end extern "C"*/
    #endif
    

    die myb_wrapper.cpp

    #include "myb_wrapper.h"
    #include "myc_wrapper.h"
    #include "C++/MyB.h" //MyB<T>
    
    WrapMyB_int myb_int_create(void)
    {
        WrapMyB_int tmp;
        tmp.ptr = new MyB<int>();
        return tmp;
    }
    void myb_int_algorithm(WrapMyB_int this_, WrapMyC_int arg)
    {
        MyB<int>* mb = static_cast<MyB<int>*> (this_.ptr);
        //mb->Algorithm(arg);
    }
    void myb_int_delete(WrapMyB_int this_)
    {
        MyB<int>* mb = static_cast<MyB<int>*> (this_.ptr);
        delete mb;
        this_.ptr = NULL;
    }
    

    und analog:
    //myc_wrapper.h

    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
        typedef struct WrapMyC_int_
        {
            void* ptr;
        } WrapMyC_int;
    
        WrapMyC_int myc_int_create(void);
    //     WrapMyC_int myc_int_create_1(int* data);
    //     void myc_int_writetobuffer(WrapMyC_int this_, int* buffer);
        void myc_int_delete(WrapMyC_int this_);
    
    #ifdef __cplusplus
    } /*end extern "C"*/
    #endif
    

    und die cpp myc_wrapper.cpp

    #include "myc_wrapper.h"
    #include "C++/MyC.h" //MyC<T>
    
    WrapMyC_int myc_int_create(void)
    {
        WrapMyC_int tmp;
        tmp.ptr = new MyC<int>();
        return tmp;
    }
    // WrapMyC_int myc_int_create_1(int* data)
    // {
    // 
    // }
    // void myc_int_writetobuffer(WrapMyC_int this_, int* buffer)
    // {
    //         /* ... */
    // }
    void myc_int_delete(WrapMyC_int this_)
    {
        MyC<int>* mc = static_cast<MyC<int>*> (this_.ptr);
        delete mc;
        this_.ptr = NULL;
    }
    

    Jetzt kompiliere ich folgendes:

    g++ -c myb_wrapper.cpp
    g++ -c myc_wrapper.cpp
    

    und erhalte objekte davon.
    Ich baue mir eine statische library über

    ar -r libmyLib.a myc_wrapper.o myb_wrapper.o
    

    Jetzt habe cih meinen C-Code:
    //mainnew.c

    //main.c
    #include "myc_wrapper.h"
    #include "myb_wrapper.h"
    
    #include "stdlib.h"
    
    int main()
    {
        int i;
        int* data = calloc(10, sizeof(int));
    
        for (i = 10; i > 0; i--)
            data[10-i] = i;
    
        /*...*/
        //MyC<int> * mtx = new MyC<int>();
        WrapMyC_int mtx = myc_int_create(); //konstruktor
    
        //MyB<int>().Algorithm(mtx);        
        WrapMyB_int tmp = myb_int_create(); //konstruktor
        //myb_int_algorithm(tmp, mtx);        //methode
    
        myc_int_delete(mtx);                //destruktor
        myb_int_delete(tmp);                //destruktor
    
        /*...*/
    //     //MyC<int>* mtx = convert_data_to_MyC(data);
    //     WrapMyC_int mtx2 = myc_int_create_1(data); //anderer konstruktor
    //    
    //     //MyB<int>().Algorithm(mtx);
    //     WrapMyB_int tmp2 = myb_int_create(); //konstruktor
    //     myb_int_algorithm(tmp2, mtx2);        //methode
    //     myc_int_writetobuffer(mtx2, data);  
    //    
    //     myc_int_delete(mtx2);                //destruktor
    //     myb_int_delete(tmp2);                //destruktor
    //     
    //     for (i = 0; i < 10; i++)
    //         printf("data[%d] = %d\n", i, data[i]);
    
        free(data);
    }
    

    Den ich kompiliere über:

    gcc -o mainnew mainnew.c -L lmyLib.a
    

    Ich erhalte aber folgende Probleme:

    /tmp/cc0e4n2e.o: In function `main':
    mainnew.c:(.text+0x57): undefined reference to `myc_int_create'
    mainnew.c:(.text+0x6b): undefined reference to `myb_int_create'
    mainnew.c:(.text+0x7f): undefined reference to `myc_int_delete'
    mainnew.c:(.text+0x8a): undefined reference to `myb_int_delete'
    collect2: ld gab 1 als Ende-Status zurück
    

    Was mache ich falsch?



  • Du mußt ein kleines 'l' für das Linken verwenden (das große 'L' bezeichnet den Pfad zu den Linkerdateien):

    gcc -o mainnew mainnew.c -lmyLib
    


  • fällt dir was auf?

    ar -r libmyLib.a myc_wrapper.o myb_wrapper.o
    
    gcc -o mainnew mainnew.c -L lmyLib.a
    

    Wie heißt die Lib denn nu wirklich?



  • und dort musst du die Templates auch auf konkrete Typen festlegen.

    was irgendwo die Templates sinnlos macht... Aber scheint mir auch die einzige vernünftige Lösung zu sein. Wobei mir der Sinn des Ganzen immernoch nicht klar ist. Sollen die "User" halt nen C++-Compiler benutzen. Man kann nunmal nicht alles haben.


Anmelden zum Antworten