如何从 C 调用 C++ 函数?

2021-12-02 00:00:00 c visual-c++ c++ extern-c

这个我知道.

从 C++ 调用 C 函数:

如果我的应用程序是用 C++ 编写的,而我必须从用 C 编写的库中调用函数.那么我会使用

If my application was in C++ and I had to call functions from a library written in C. Then I would have used

//main.cpp

extern "C" void C_library_function(int x, int y);//prototype
C_library_function(2,4);// directly using it.

这不会破坏名称 C_library_function 并且链接器会在其输入的 *.lib 文件中找到相同的名称,问题就解决了.

This wouldn't mangle the name C_library_function and linker would find the same name in its input *.lib files and problem is solved.

从 C 调用 C++ 函数???

但是在这里我要扩展一个用 C 编写的大型应用程序,我需要使用一个用 C++ 编写的库.C++ 的名称修改在这里造成了麻烦.链接器抱怨未解析的符号.好吧,我不能在我的 C 项目上使用 C++ 编译器,因为那会破坏很多其他东西.出路是什么?

But here I'm extending a large application which is written in C and I need to use a library which is written in C++. Name mangling of C++ is causing trouble here. Linker is complaining about the unresolved symbols. Well I cannot use C++ compiler over my C project because thats breaking lot of other stuff. What is the way out?

顺便说一下,我正在使用 MSVC

By the way I'm using MSVC

推荐答案

您需要创建一个 C API 来公开您的 C++ 代码的功能.基本上,您将需要编写声明为 extern "C" 并且具有包装 C++ 库的纯 C API(例如不使用类)的 C++ 代码.然后使用您创建的纯 C 包装器库.

You need to create a C API for exposing the functionality of your C++ code. Basically, you will need to write C++ code that is declared extern "C" and that has a pure C API (not using classes, for example) that wraps the C++ library. Then you use the pure C wrapper library that you've created.

您的 C API 可以选择遵循面向对象的风格,即使 C 不是面向对象的.例如:

Your C API can optionally follow an object-oriented style, even though C is not object-oriented. Ex:

 // *.h file
 // ...
 #ifdef __cplusplus
 #define EXTERNC extern "C"
 #else
 #define EXTERNC
 #endif

 typedef void* mylibrary_mytype_t;

 EXTERNC mylibrary_mytype_t mylibrary_mytype_init();
 EXTERNC void mylibrary_mytype_destroy(mylibrary_mytype_t mytype);
 EXTERNC void mylibrary_mytype_doit(mylibrary_mytype_t self, int param);

 #undef EXTERNC
 // ...


 // *.cpp file
 mylibrary_mytype_t mylibrary_mytype_init() {
   return new MyType;
 }

 void mylibrary_mytype_destroy(mylibrary_mytype_t untyped_ptr) {
    MyType* typed_ptr = static_cast<MyType*>(untyped_ptr);
    delete typed_ptr;
 }

 void mylibrary_mytype_doit(mylibrary_mytype_t untyped_self, int param) {
    MyType* typed_self = static_cast<MyType*>(untyped_self);
    typed_self->doIt(param);
 }

相关文章