2013-05-27 9 views
5

Wiem, że to nie jest dobry sposób na rozwijanie projektu, ale z pewnych powodów mojej pracy jestem zaangażowany w integrację niektórych struktur danych w C++ (pamięć podręczna LRU i mapa skrótu) w Projekt C.Kod C ze strukturami danych C++

Do tej pory wiem, że jest jakiś sposób wywoływania funkcji C w C++ przy użyciu extern "C", ale co z wywołaniem obiektów C++ (metod ...) z C?

Używam GCC.

+1

AFAIK, nie można. Nie bez dostarczania wrapperów C dla funkcji C++ i eksponowania obiektów jako struktur/nieprzezroczystych wskaźników. (No cóż, używanie wskaźników w C++ jest "złe".) – millimoose

Odpowiedz

6

Jeśli cały kod jest kompilowany przy użyciu kompilatora C++, problem nie powinien być (lub bardzo mały).

Jeśli posiadasz C skompilowany z gcc i C++ skompilowanym za pomocą g ++, musisz napisać wrapper nagłówka wokół swojej klasy, aby kod C++ był widoczny przez zestaw funkcji.

Przykład:

MyClass.h

#ifdef __cplusplus 


class MyClass 
{ 
    public: 
     MyClass() {/*STUFF*/} 
     ~MyClass() {/*STUFF*/} 

     int doStuff(int x, float y) {/*STUFF*/} 
}; 

extern "C" { 
#endif 

/* C Interface to MyClass */ 

void* createMyClass(); 
void destroyMyClass(void* mc); 
int  doStuffMyClass(void* mc, int x, float y); 

#ifdef __cplusplus 
} 
#endif 

Plik źródłowy

MyClass.cpp

#include "MyClass.h" 

void* createMyClass()   {return reinterpret_cast<void*>(new MyClass);} 
void destroyMyClass(void* mc) {delete reinterpret_cast<MyClass*>(mc);} 

int  doStuffMyClass(void* mc, int x, float y) 
{ 
    return reinterpret_cast<MyClass*>(mc)->doStuff(x,y); 
} 

Twój kod C teraz właśnie to "MyClass.h" i wykorzystuje Zapewnione funkcje C.

MyCFile.c

#include "MyClass.h" 

int main() 
{ 
    void* myClass = createMyClass(); 
    int value = doStuffMyClass(myClass, 5, 6.0); 
    destroyMyClass(myClass); 
} 
+0

+1 Bardzo kompletna odpowiedź! –

6

Napisz opakowanie C wokół swojego interfejsu C++. Skompiluj go jako C++, ale upewnij się, że umieściłeś swój interfejs C w bloku extern "C". Ten nowy interfejs powinien łączyć grzywnę z twoim programem C i zapewniać dostęp do twojego kodu C++.

5

Należy utworzyć funkcje przekazywania zgodnego z C, które jako pierwszy parametr będą stanowić wskaźnik do obiektu. Funkcja przekazująca następnie [zazwyczaj] rzuci pierwszy parametr do poprawnego typu obiektu i wywoła odpowiednią funkcję składową.

// Function declaration in header 
extern "C" void function(void *object, int param1, int param2); 

// Function definition in source file 
extern "C" function(void *object, int param1, int param2) 
{ 
    static_cast<Object*>(object)->member_function(param1, param2); 
} 
+0

+1, ta odpowiedź jest dobrym przykładem tego, do czego dążyłem. –

+2

Nie zapomnij o '#ifdef __cplusplus' wokół' extern 'C "' w nagłówkach, aby mogły być użyte z C, i wychwycić każdy wyjątek, który może powstać w kodzie C++ (C nie lubi wyjątków. ..). Ponadto, zamiast używać "void *" dla wskaźników obiektów, można chcieć przekazać dalej - zadeklarować, że "struktura" ma minimalne bezpieczeństwo. – syam