Zrobiłbym to w następujący sposób:
(Jeśli pracujesz z MSVC, zignoruj polecenia kompilacji GCC)
Załóżmy, że mam klasę C ++ o nazwie AAA , zdefiniowaną w plikach aaa.h, aaa.cpp i że klasa AAA ma metodę o nazwie sayHi (const char * name) , którą chcę włączyć dla kodu C.
Kod C ++ klasy AAA - Czysty C ++, nie modyfikuję go:
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;
}
Kompilowanie tej klasy w sposób regularny dla C ++. Ten kod „nie wie”, że będzie używany przez kod C. Za pomocą polecenia:
g++ -fpic -shared aaa.cpp -o libaaa.so
Teraz, także w C ++, tworzenie łącznika C. Definiowanie go w plikach aaa_c_connector.h, aaa_c_connector.cpp . Ten łącznik zdefiniuje funkcję C o nazwie AAA_sayHi (cosnt char * name) , która będzie używać instancji AAA i wywoła swoją metodę:
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
Kompiluję go ponownie, używając zwykłego polecenia kompilacji C ++:
g++ -fpic -shared aaa_c_connector.cpp -L. -laaa -o libaaa_c_connector.so
Teraz mam udostępnioną bibliotekę (libaaa_c_connector.so), która implementuje funkcję C AAA_sayHi (const char * name) . Mogę teraz utworzyć główny plik C i skompilować wszystko razem:
main.c
#include "aaa_c_connector.h"
int main() {
AAA_sayHi("David");
AAA_sayHi("James");
return 0;
}
Kompilowanie go za pomocą polecenia kompilacji w C:
gcc main.c -L. -laaa_c_connector -o c_aaa
Będę musiał ustawić LD_LIBRARY_PATH tak, aby zawierał $ PWD, a jeśli uruchomię plik wykonywalny ./c_aaa , otrzymam oczekiwany wynik:
Hi David
Hi James
EDYTOWAĆ:
W niektórych dystrybucjach Linuksa -laaa
i -lstdc++
może być również wymagane dla ostatniego polecenia kompilacji. Dzięki @AlaaM. dla uwagi