tôi sẽ làm điều đó theo cách sau:
(Nếu làm việc với MSVC, bỏ qua các lệnh GCC biên soạn)
Giả sử rằng tôi có một ++ lớp C tên AAA, được định nghĩa trong file aaa .h, aaa.cpp và lớp AAA có phương thức có tên sayHi (const char * name), mà tôi muốn bật cho mã C.
Các mã C++ lớp AAA - Pure C++, tôi không sửa đổi nó:
// 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;
}
Biên soạn lớp này như thường xuyên làm cho C++. Mã này "không biết" rằng nó sẽ được sử dụng bởi mã C. Sử dụng lệnh:
g++ -fpic -shared aaa.cpp -o libaaa.so
Bây giờ, cũng trong C++, tạo ra một kết nối C. Xác định nó trong các tệp aaa_c_connector.h, aaa_c_connector.cpp. kết nối này sẽ định nghĩa một hàm C, tên AAA_sayHi (cosnt char * name), mà sẽ sử dụng một thể hiện của AAA và sẽ gọi phương thức của nó:
// 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
biên soạn nó, một lần nữa, bằng cách sử dụng C++ thường lệnh biên soạn:
g++ -fpic -shared aaa_c_connector.cpp -L. -laaa -o libaaa_c_connector.so
Bây giờ tôi có một thư viện chia sẻ (libaaa_c_connector.so), mà thực hiện chức năng C AAA_sayHi (const char * name). bây giờ tôi có thể tạo một tập tin chính C và biên dịch nó tất cả cùng nhau:
// main.c
#include "aaa_c_connector.h"
int main() {
AAA_sayHi("David");
AAA_sayHi("James");
return 0;
}
Biên soạn nó bằng cách sử dụng lệnh C biên soạn:
gcc main.c -L. -laaa_c_connector -o c_aaa
tôi sẽ cần phải thiết lập LD_LIBRARY_PATH chứa $ PWD và nếu tôi chạy tệp thực thi ./c_aaa, tôi sẽ nhận được kết quả mong đợi:
Hi David
Hi James
EDIT:
Trên một số bản phân phối Linux, -laaa
và -lstdc++
cũng có thể được yêu cầu cho lệnh biên dịch cuối cùng. Nhờ @AlaaM. cho sự chú ý
Đọc http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.6 – jweyrich
Khi bạn kiểm soát thư viện C++: http: // stackoverflow. com/questions/12615683/calling-c-functions-from-c-file –
Có thể trùng lặp của [Elegantly call C++ from C] (http://stackoverflow.com/questions/7281441/elegantly-call-c-from-c) – user2284570