2013-03-16 9 views

risposta

4

Avrai bisogno di "avvolgere" l'interfaccia C++ con funzioni regolari C che prendono un parametro per indicare quale oggetto che Sarò chiamato. Ad esempio, se si hanno in C++

class A 
{ 
    // .. boilerplate stuff... 
    int SomeMethod(int n, float f); 
}; 

Poi insieme ad esso, si potrebbe dichiarare una funzione come

extern "C" int A_SomeMethod(void* Obj, int n, float f) 
{ 
    return(((A*)Obj)->SomeMethod(n, f)); 
} 

Se non stai bene con il getto del vuoto *, è possibile implementare un tipo di mappa da un handle opaco a uno A*. Ma l'essenza è che dovrete mantenere un po 'di handle/puntatore all'oggetto sul quale verrà chiamato il metodo. Al fine di ottenere il puntatore/maniglia è necessario avvolgere l'assegnazione di: file

extern "C" void* A_Instantiate() 
{ 
    return new A; 
} 

C++ devono essere compilate separatamente insieme con il file con le funzioni di cui sopra. Un allegato separato per la compilazione C dovrebbe includere le dichiarazioni di tutte le funzioni di cui sopra.

MODIFICA: le avvertenze e i commenti riportati di seguito sono importanti; per rispondere alla domanda, "Sì, è possibile chiamare C++ da C", e questo è un approccio. Non è un approccio completo in quanto non esiste un modo meccanicistico per farlo, ma è un inizio. Inoltre, non dimenticare di creare un altro call-through per delete, ecc, ecc

+0

Grazie a wilsonmichaelpatrick, ma che ne è dell'utilizzo del codice * Compiled * C++ nel mio programma C ?! – S0H31L

+0

Che cosa è 'A' che viene usato per lanciare' Obj' ?! È un tipo o struttura predefinito ?! – S0H31L

+0

'A' è il tipo di classe C++. Anche con codice C++ compilato, questo approccio dovrebbe funzionare. Tutto quello che devi fare è definire i metodi extern "C" lungo le linee che ho descritto sopra, e usarli per chiamare il tuo codice C++. Il codice C++ stesso non deve essere modificato. – wilsonmichaelpatrick

0

sì, è necessario specificare come

extern "C"

questo modo si renderà la funzione di avere "C" linkage, quindi il codice C può chiamare la funzione basta come se fosse in C. Questo nome di funzione non verrà alterato perché C non supporta il sovraccarico.

qui mi permetta di citare @Faisal Vali:

  • extern "C" è un legame-specifica
  • Ogni compilatore è necessario per fornire il collegamento "C"
  • una specifica legame si verifica solo nello spazio namespace
  • tutti i tipi di funzione, nomi di funzioni e nomi di variabili hanno un collegamento linguistico
  • due tipi di funzione con lingua distinta legami ge sono tipi distinti anche se altrimenti identica
  • caratteristiche linkage nido, uno interno determina il collegamento finale
  • extern "C" viene ignorato per i membri della classe
  • al massimo una funzione con un nome particolare può avere "C" collegamento (indipendentemente dallo spazio dei nomi)
  • extern "C" forza una funzione per il collegamento esterno (non può renderlo statico)
  • Il collegamento da C++ agli oggetti definiti in altri linguaggi e agli oggetti definiti in C++ da altre lingue è l'implementazione- definito e dipendente dalla lingua. Solo dove le strategie di layout oggetto di due implementazioni di lingua sono abbastanza simili possono tale collegamento essere raggiunto

see Faisal Vali answer here

+0

Funzionerà solo per le funzioni compatibili con C (_una_ versione delle funzioni sovraccaricate, se il sovraccarico in questo viene addirittura gestito, nessun riferimento, sicuramente non le funzioni membro, né per classi né oggetti, possono utilizzare oggetti e classi internamente _solo_ e con molte restrizioni). Questo non è l'intento dello standard, è essere in grado di chiamare in C da C++, non viceversa; quindi potrebbe anche essere disabilitato dal tuo toolchain C++/C. – vonbrand

0

D: Posso accedere al mio codice C da C++ o viceversa?

A: Sì.

1) La cosa più importante è quella di utilizzare extern "C" { ...} in tutte le intestazioni per indicare funzioni e dati C-solo, in questo modo:

http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B

/* Header file foo.h */ 
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */ 
extern "C" { 
#endif 

/* These functions get C linkage */ 
void foo(); 

struct bar { /* ... */ }; 

#ifdef __cplusplus /* If this is a C++ compiler, end C linkage */ 
} 
#endif 

2) Lo scenario al solito è un C++ principale programma che chiama un mix di funzioni e strutture C e C++. Le strutture e le funzioni sono tutte dichiarate nelle intestazioni e tutte hanno "#ifdef __cplusplus/extern C".

3) Ecco una buona FAQ sul mescolando C e C++:

http://www.parashift.com/c++-faq/mixing-c-and-cpp.html

+2

Da quello che ho letto: questo è un progetto in C, che sta cercando di chiamare un codice C++, e si sta rispondendo come se fosse un programma C++ che chiama le funzioni C. – qdii

+0

@ paulsm4: tnx per la tua risposta, ma qdii ha ragione :) – S0H31L

0

A meno strettamente necessario, questo è solo per masochisti dyied-in-the-lana. Farlo richiederà una cura estrema da entrambe le parti, e potrebbe benissimo funzionare oggi ed esplodere in modo spettacolare con il prossimo aggiornamento del compilatore. C++ richiede molto aiuto in fase di runtime, e ottenere che funzioni in modo affidabile da C non è normalmente supportato. Puoi chiamare in C da C++, che è ufficialmente supportato (e parte dello standard, extern "C" e così via).

Probabilmente la soluzione migliore è scrivere la C nel sottoinsieme gestito da C e C++ (un punto di partenza sulle sottili differenze è this) e compilare con il compilatore C++. Oppure passaci sopra e decidi quale lingua ti piace di più.

+0

grazie, e riguardo l'uso del codice C++ compilato nel mio programma C ?! P.S: È * Richiesto rigorosamente! *: S – S0H31L

+0

Compilare con un compilatore C++. Qualsiasi altra cosa è follia. La ragione per non usare C++ è un problema legato alla lingua (il programmatore non conosce la lingua, contro la politica, è considerato troppo inefficiente, qualunque) o a causa dei requisiti di runtime. I primi possono essere risolti e usare C++ in modo uniforme; il secondo costa che pagherai comunque con una chimera, a parte i problemi extra dovuti alla combinazione linguistica. – vonbrand