2010-01-16 17 views
5

C'è qualche consiglio che mi può dare circa il passaggio di puntatori a strutture, doppi, funzioni, ... da un programma C a una libreria C++ e viceversa?passando i puntatori da C a C++ e viceversa

+3

Questa è una buona domanda in generale, tuttavia, dando un esempio di caso di utilizzo in cui avete domande più specifiche aiuteranno la comunità dare i migliori consigli. –

risposta

10

Supponendo che si sta codifica questi in due diverse librerie statiche o dinamiche (DLL su Windows librerie condivise su Linux e altre varianti * nix) più grandi preoccupazioni che ho sono i seguenti:

  1. Sono compilati con lo stesso compilatore. Sebbene ciò non sia necessario se tutte le esportazioni C++ vengono esportate con una convenzione di denominazione in stile C, è necessario per le chiamate da C++ a C++ alle istanze di classe tra i due moduli C++. Ciò è necessario a causa del modo in cui i diversi compilatori distruggono le esportazioni C++ in modo diverso.

  2. Non eseguire il cast di una classe C++ come struttura C. Non sono uguali sotto le coperte, anche se il layout dei campi è lo stesso. Le classi C++ hanno una "v-table" se hanno membri virtuali; questa tabella v consente il corretto richiamo dei metodi di classe ereditari o di base.

  3. Questo vale per C a C o da C++ a C++ nonché da C a C++. Assicurarsi che entrambi utilizzino lo stesso allineamento di byte per la libreria di output. È possibile determinarlo solo leggendo la documentazione del compilatore o degli ambienti di sviluppo.

  4. Non mescolare malloc/free con new/delete. Più specificamente non allocare memoria con memoria nuova e libera con "libero" e viceversa. Molti compilatori e sistemi operativi gestiscono la gestione della memoria in modo diverso tra i due.

  5. Passaggio di puntatori di funzione: Fintanto che sono esposti a/da C++ come "extern" C "" questo dovrebbe essere corretto. (Avrai bisogno di fare riferimento alla documentazione del tuo compilatore su come determinare quando un'intestazione viene compilata come C o C++ per mantenerla in un file, o avrai bisogno di due copie separate della stessa dichiarazione di funzione in ogni progetto - I raccomandare il primo)

  6. Passare doppio: questo è un tipo predefinito in C e C++ e deve essere gestito allo stesso modo.

  7. Se è necessario condividere un'istanza di un oggetto C++ con una funzione C e agire su di esso dal codice C, esporre un set di funzioni helper esportate da C che chiamano i metodi appropriati sull'oggetto C++. Il codice Pure C non può correttamente chiamare metodi su oggetti C++.

 

    Pseudocode-ish Example: 
    // C++ class 
    class foo { 
     public: 
      void DoIt(); 
    }; 

    // export helper declarations 
    extern "C" void call_doit(foo* pFoo); 
    extern "C" foo* allocate_foo(); 
    extern "C" deallocate_foo(foo* pFoo); 


    // implementation 
    void call_doit(foo* pFoo) 
    { 
     pFoo->DoIt(); 
    } 

    foo* allocate_foo() 
    { 
     return new foo(); 
    } 

    deallocate_foo(foo* pFoo) 
    { 
     delete pFoo; 
    } 

    // c consumer 
    void main() 
    { 
     foo* pFoo= allocate_foo(); 
     call_doit(pFoo); 
     dealocate_foo(pFoo); 
    } 

 
+0

Probabilmente vale la pena leggere questo post: http://stackoverflow.com/questions/2045774/developing-c-wrapper-api-for-object-oriented-c-code –

0

I puntatori C e C++ sono gli stessi: un puntatore indica fondamentalmente un blocco di memoria, che non cambia passando da C/C++.

Si vuole fare attenzione a non incrociare i tipi di heap, ad esempio non allocare in una libreria e disallocare in una libreria che potrebbe avere un altro heap o utilizzare un'altra versione di runtime (o viceversa) .

Intendevi chiedere informazioni sul pass-by-value o sul pass-by-reference? Potrebbe aiutare a fornire una domanda più concreta.

+0

E i puntatori alle funzioni? – adk

+0

i puntatori alle funzioni (non ai metodi) sono gli stessi in C++ come in C. Tuttavia, è necessario definirli con 'extern" C "' per non farli venire manomessi – psychotik

0
  • non dimenticare il extern "C" parola chiave per problema evitano con il C++ pressare nome.
  • Non usare passaggio dal tipo di argomento di riferimento ma puntatore