Ich würde es folgendermaßen machen:
(Wenn Sie mit MSVC arbeiten, ignorieren Sie die GCC-Kompilierungsbefehle.)
Angenommen, ich habe eine C ++ - Klasse namens AAA , die in den Dateien aaa.h, aaa.cpp definiert ist , und die Klasse AAA hat eine Methode namens sayHi (const char * name) , die ich für C-Code aktivieren möchte.
Den C ++ - Code der Klasse AAA - Pure C ++ ändere ich nicht:
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;
}
Kompilieren dieser Klasse wie regelmäßig für C ++ durchgeführt. Dieser Code "weiß nicht", dass er von C-Code verwendet wird. Verwenden des Befehls:
g++ -fpic -shared aaa.cpp -o libaaa.so
Jetzt auch in C ++ einen C-Connector erstellen. Definieren in den Dateien aaa_c_connector.h, aaa_c_connector.cpp . Dieser Connector definiert eine C-Funktion namens AAA_sayHi (cosnt char * name) , die eine Instanz von AAA verwendet und deren Methode aufruft :
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
// Inside this "extern C" block, I can implement functions in C++, which will externally
// appear as C functions (which means that the function IDs will be their names, unlike
// the regular C++ behavior, which allows defining multiple functions with the same name
// (overloading) and hence uses function signature hashing to enforce unique IDs),
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
Kompilieren Sie es erneut mit einem regulären C ++ - Kompilierungsbefehl:
g++ -fpic -shared aaa_c_connector.cpp -L. -laaa -o libaaa_c_connector.so
Jetzt habe ich eine gemeinsam genutzte Bibliothek (libaaa_c_connector.so), die die C-Funktion AAA_sayHi (const char * name) implementiert . Ich kann jetzt eine C-Hauptdatei erstellen und alles zusammen kompilieren:
main.c
#include "aaa_c_connector.h"
int main() {
AAA_sayHi("David");
AAA_sayHi("James");
return 0;
}
Kompilieren mit einem C-Kompilierungsbefehl:
gcc main.c -L. -laaa_c_connector -o c_aaa
Ich muss LD_LIBRARY_PATH so einstellen, dass es $ PWD enthält, und wenn ich die ausführbare Datei ./c_aaa ausführe, erhalte ich die erwartete Ausgabe:
Hi David
Hi James
BEARBEITEN:
Unter einigen Linux-Distributionen -laaa
und -lstdc++
möglicherweise auch für den letzten Kompilierungsbefehl erforderlich. Danke an @AlaaM. für die Aufmerksamkeit