Я хотел бы сделать это следующим образом:
(При работе с MSVC, игнорировать команды GCC компиляции)
Предположим, что у меня есть класс C++ с именем AAA, определены в файлах aaà .h, aaa.cpp и что класс AAA имеет метод с именем sayHi (const char * name), который я хочу включить для кода C.
код C++ класса AAA - Pure C++, я не изменить его:
// ааа.ч
#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;
}
Компиляция этот класс как регулярно делается для C++. Этот код «не знает», что он будет использоваться кодом C. С помощью команды:
g++ -fpic -shared aaa.cpp -o libaaa.so
Теперь и в C++, создавая разъем C. Определение его в файлах aaa_c_connector.h, aaa_c_connector.cpp. Этот разъем будет определять функцию C, названный AAA_sayHi (cosnt символ * имя), который будет использовать экземпляр AAA и вызвать его метод:
// 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 define C functions that are able to call C++ code
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
компиляция это, опять же, с помощью обычного C++ команда компиляции:
g++ -fpic -shared aaa_c_connector.cpp -L. -laaa -o libaaa_c_connector.so
Теперь у меня есть общая библиотека (libaaa_c_connector.so), которая реализует функцию C AAA_sayHi (Const символ * имя). Теперь я могу создать главный файл C и собрать все это вместе:
// main.c
#include "aaa_c_connector.h"
int main() {
AAA_sayHi("David");
AAA_sayHi("James");
return 0;
}
Компиляция его с помощью команды C компиляции:
gcc main.c -L. -laaa_c_connector -o c_aaa
мне нужно будет установить LD_LIBRARY_PATH содержит $ PWD, и если я запустить исполняемый файл ./c_aaa, я получаю выход я ожидаю:
Hi David
Hi James
EDIT:
В некоторых дистрибутивах Linux, -laaa
и -lstdc++
также может потребоваться для выполнения последней команды компиляции. Благодаря @AlaaM. для внимания
Прочтите http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.6 – jweyrich
Когда вы управляете библиотекой C++: http: // stackoverflow. com/questions/12615683/call-c-functions-from-c-file –
Возможный дубликат [Элегантный вызов C++ с C] (http://stackoverflow.com/questions/7281441/elegantly-call-c-from-c) – user2284570