Tệp tiêu đề của bạn, được chia sẻ giữa mã C và C ++ của bạn:
#ifdef __cplusplus // only actually define the class if this is C++
class some_class
{
public:
int some_method[float];
};
#else
// C doesn't know about classes, just say it's a struct
typedef struct some_class some_class;
#endif
// access functions
#ifdef __cplusplus
#define EXPORT_C extern "C"
#else
#define EXPORT_C
#endif
EXPORT_C some_class* some_class_new[void];
EXPORT_C void some_class_delete[some_class*];
EXPORT_C int some_class_some_method[some_class*, float];
Sau đó, tệp nguồn của bạn:
#include "some_foo.h"
int some_class::some_method[float f]
{
return static_cast[f];
}
// access functions
EXPORT_C some_class* some_class_new[void]
{
return new some_class[];
}
EXPORT_C void some_class_delete[some_class* this]
{
delete this;
}
EXPORT_C int some_class_some_method[some_class* this, float f]
{
return this->some_method[f];
}
Bây giờ biên dịch nguồn đó và liên kết với nó. Nguồn C của bạn sẽ giống như:
#include "some_class.h"
some_class* myInstance = some_class_new[];
int i = some_class_some_method[myInstance, 10.0f];
some_class_delete[myInstance];
Nếu bạn nghiêm túc về việc trộn C và C ++, bạn sẽ muốn Macro.
Dưới đây là một số mẫu Macro sẽ giúp điều này dễ dàng hơn nhiều:
// in something like c_export.h
// extern "C" macro
#ifdef __cplusplus
#define EXPORT_C extern "C"
#else
#define EXPORT_C
#endif
// new
#define EXPORT_C_CLASS_NEW[classname] EXPORT_C \
classname * classname##_new[void]
#define EXPORT_C_CLASS_NEW_DEFINE[classname] \
EXPORT_C_CLASS_NEW[classname] \
{ return new classname []; }
// repeat as much as you want. allows passing parameters to the constructor
#define EXPORT_C_CLASS_NEW_1[classname, param1] EXPORT_C \
classname * classname##_new[ param1 p1]
#define EXPORT_C_CLASS_NEW_1_DEFINE[classname, param1] \
EXPORT_C_CLASS_NEW_1[classname, param1] \
{ return new classname [p1]; }
// delete
#define EXPORT_C_CLASS_DELETE[classname] EXPORT_C \
void classname##_delete[ classname * this]
#define EXPORT_C_CLASS_DELETE_DEFINE[classname] \
EXPORT_C_CLASS_DELETE[classname] \
{ delete this; }
// functions
#define EXPORT_C_CLASS_METHOD[classname, methodname, ret] EXPORT_C \
ret classname##_##methodname##[ classname * this]
#define EXPORT_C_CLASS_METHOD_DEFINE[classname, methodname, ret] \
EXPORT_C_CLASS_METHOD[classname, methodname, ret] \
{ return this->##methodname##[]; }
// and repeat as necessary.
#define EXPORT_C_CLASS_METHOD_1[classname, methodname, ret, param1] EXPORT_C \
ret classname##_##methodname[ classname * this, param1 p1]
#define EXPORT_C_CLASS_METHOD_1_DEFINE[classname, methodname, ret, param1] \
EXPORT_C_CLASS_METHOD_1[classname, methodname, ret, param1] \
{ return this->##methodname##[p1]; }
Và như thế. Tiêu đề/nguồn của chúng tôi trở thành:
// header
#include "c_export.h" // utility macros
#ifdef __cplusplus // only actually define the class if this is C++
class some_class
{
public:
int some_method[float];
};
#else
// C doesn't know about classes, just say it's a struct
typedef struct some_class some_class;
#endif
// access functions
EXPORT_C_CLASS_NEW[some_class];
EXPORT_C_CLASS_DELETE[some_class];
EXPORT_C_CLASS_METHOD_1[some_class, some_method, int, float];
// source
#include "some_foo.h"
int some_class::some_method[float f]
{
return static_cast[f];
}
// access functions
EXPORT_C_CLASS_NEW_DEFINE[some_class];
EXPORT_C_CLASS_DELETE_DEFINE[some_class];
EXPORT_C_CLASS_METHOD_1_DEFINE[some_class, some_method, int, float];
Và điều đó ngắn gọn hơn nhiều. Nó có thể được thực hiện đơn giản hơn [có thể] với Variadic Macro, nhưng đó là không chuẩn và tôi để nó cho bạn. :] Ngoài ra, bạn có thể tạo Macro cho các chức năng không phải thành viên bình thường.
Lưu ý rằng C không biết tài liệu tham khảo là gì. Nếu bạn muốn liên kết với một tài liệu tham khảo, đặt cược tốt nhất của bạn có lẽ chỉ là viết định nghĩa xuất theo cách thủ công. [Nhưng tôi sẽ nghĩ về nó, có lẽ chúng ta có thể tự động lấy nó].
Hãy tưởng tượng some_class
của chúng tôi đã lấy float
bằng cách tham chiếu [không phải con quay] [vì bất kỳ lý do gì]. Chúng tôi sẽ xác định chức năng như vậy:
// header
// pass by pointer! v
EXPORT_C_CLASS_METHOD_1[some_class, some_method, int, float*] ;
// source
EXPORT_C_CLASS_METHOD_1[some_class, some_method, int, float*]
{
// dereference pointer; now can be used as reference
return this->some_method[*p1];
}
Và chúng tôi đi. C sẽ giao diện với các tài liệu tham khảo với con trỏ thay thế:
// c source, if some_method took a reference:
float f = 10.0f;
int i = some_class_some_method[myInstance, &f];
Và chúng tôi vượt qua f
"bằng cách tham khảo".