Lo farei nel modo seguente:
(Se lavori con MSVC, ignora i comandi di compilazione GCC)
Supponiamo che io abbia una classe C ++ chiamata AAA , definita nei file aaa.h, aaa.cpp , e che la classe AAA abbia un metodo chiamato sayHi (const char * name) , che voglio abilitare per il codice C.
Il codice C ++ della classe AAA - Pure C ++, non lo modifico:
aaa.h
#ifndef AAA_H
#define AAA_H
class AAA {
public:
AAA();
void sayHi(const char *name);
};
#endif
aaa.cpp
#include <iostream>
#include "aaa.h"
AAA::AAA() {
}
void AAA::sayHi(const char *name) {
std::cout << "Hi " << name << std::endl;
}
Compilando questa classe come si fa regolarmente per C ++. Questo codice "non sa" che verrà utilizzato dal codice C. Utilizzando il comando:
g++ -fpic -shared aaa.cpp -o libaaa.so
Ora, anche in C ++, creando un connettore C. Definendolo nei file aaa_c_connector.h, aaa_c_connector.cpp . Questo connettore definirà una funzione C, denominata AAA_sayHi (cosnt char * name) , che utilizzerà un'istanza di AAA e chiamerà il suo metodo:
aaa_c_connector.h
#ifndef AAA_C_CONNECTOR_H
#define AAA_C_CONNECTOR_H
#ifdef __cplusplus
extern "C" {
#endif
void AAA_sayHi(const char *name);
#ifdef __cplusplus
}
#endif
#endif
aaa_c_connector.cpp
#include <cstdlib>
#include "aaa_c_connector.h"
#include "aaa.h"
#ifdef __cplusplus
extern "C" {
#endif
static AAA *AAA_instance = NULL;
void lazyAAA() {
if (AAA_instance == NULL) {
AAA_instance = new AAA();
}
}
void AAA_sayHi(const char *name) {
lazyAAA();
AAA_instance->sayHi(name);
}
#ifdef __cplusplus
}
#endif
Compilarlo, di nuovo, usando un normale comando di compilazione C ++:
g++ -fpic -shared aaa_c_connector.cpp -L. -laaa -o libaaa_c_connector.so
Ora ho una libreria condivisa (libaaa_c_connector.so), che implementa la funzione C AAA_sayHi (const char * name) . Ora posso creare un file principale C e compilarlo tutto insieme:
main.c
#include "aaa_c_connector.h"
int main() {
AAA_sayHi("David");
AAA_sayHi("James");
return 0;
}
Compilarlo utilizzando un comando di compilazione C:
gcc main.c -L. -laaa_c_connector -o c_aaa
Dovrò impostare LD_LIBRARY_PATH per contenere $ PWD e se eseguo l'eseguibile ./c_aaa , otterrò l'output che mi aspetto:
Hi David
Hi James
MODIFICARE:
Su alcune distribuzioni Linux, -laaa
e -lstdc++
potrebbe anche essere richiesto per l'ultimo comando di compilazione. Grazie a @AlaaM. per l'attenzione