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
risposta
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:
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.
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.
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.
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.
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)
Passare doppio: questo è un tipo predefinito in C e C++ e deve essere gestito allo stesso modo.
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);
}
Probabilmente vale la pena leggere questo post: http://stackoverflow.com/questions/2045774/developing-c-wrapper-api-for-object-oriented-c-code –
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.
- 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
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. –