如何调用 C++来自 C 的函数?
我知道这一点。
从 C++ 调用 C 函数:
如果我的应用程序是用 C++ 编写的,并且我必须从用 C 编写的库中调用函数。那么我会使用
//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 文件中找到相同的名称,问题就解决了。
从 C 调用 C++ 函数???
但在这里我正在扩展一个用 C 编写的大型应用程序,并且我需要使用一个用 C++ 编写的库。 C++ 的名称修改在这里造成了麻烦。链接器抱怨未解析的符号。嗯,我不能在我的 C 项目上使用 C++ 编译器,因为这会破坏很多其他东西。出路何在?
顺便说一句,我正在使用 MSVC
I know this.
Calling C function from 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.
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.
Calling C++ function from 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?
By the way I'm using MSVC
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
将 C++ 函数导出为 extern "C"(又名 C 样式符号),或者在创建 C++ 库时使用 .def 文件格式为 C++ 链接器定义未修饰的导出符号,那么 C 链接器应该可以轻松读取它
export your C++ functions as extern "C" (aka C style symbols), or use the .def file format to define undecorated export symbols for the C++ linker when it creates the C++ library, then the C linker should have no troubles reading it
您需要创建一个 C API 来公开 C++ 代码的功能。基本上,您需要编写声明为 extern“C” 的 C++ 代码,并且具有包装 C++ 库的纯 C API(例如,不使用类)。然后,您可以使用您创建的纯 C 包装器库。
即使 C 不是面向对象的,您的 C API 也可以选择遵循面向对象的风格。前任:
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.
Your C API can optionally follow an object-oriented style, even though C is not object-oriented. Ex:
我将按以下方式执行此操作:(
如果使用 MSVC,请忽略 GCC 编译命令)
假设我有一个名为 AAA 的 C++ 类,在文件 aaa.h、aaa.h 和 aaa.h 中定义。 cpp,并且类 AAA 有一个名为
sayHi(const std::string &name)
的方法,我想为 C 代码启用该方法。类 AAA 的 C++ 代码 - 纯 C++,我不修改它:
aaa.h
aaa.cpp
按照常规方式编译此类对于C++。该代码“不知道”它将被 C 代码使用。使用命令:
现在,同样在 C++ 中,创建 C 连接器:
在文件 aaa_c_connector.h、aaa_c_connector.cpp 中定义它。此连接器将定义一个带有 C++ 实现的 C 函数,名为 AAA_sayHi(cosnt char *name),它将使用 AAA 的实例并将调用它的方法:
aaa_c_connector.h
aaa_c_connector.cpp
使用常规 C++ 编译命令再次编译它:
现在我有一个共享库(libaaa_c_connector.so),它实现了 C 函数
AAA_sayHi(const char *name)
。我现在可以创建一个 C 主文件并将其全部编译在一起:main.c
使用 C 编译命令进行编译:
我需要设置 LD_LIBRARY_PATH 以包含 $PWD,并且如果我运行可执行文件 < strong>./c_aaa,我将得到我期望的输出:
编辑:
在某些 Linux 发行版上,
-laaa
和-lstdc++
可能也需要最后的编译命令。感谢@AlaaM。为了引起注意I would do it in the following way:
(If working with MSVC, ignore the GCC compilation commands)
Suppose that I have a C++ class named AAA, defined in files aaa.h, aaa.cpp, and that the class AAA has a method named
sayHi(const std::string &name)
, that I want to enable for C code.The C++ code of class AAA - Pure C++, I don't modify it:
aaa.h
aaa.cpp
Compiling this class as regularly done for C++. This code "does not know" that it is going to be used by C code. Using the command:
Now, also in C++, creating a C connector:
Defining it in files aaa_c_connector.h, aaa_c_connector.cpp. This connector is going to define a C function with C++ implementation, named
AAA_sayHi(cosnt char *name)
, that will use an instance of AAA and will call its method:aaa_c_connector.h
aaa_c_connector.cpp
Compiling it, again, using a regular C++ compilation command:
Now I have a shared library (libaaa_c_connector.so), that implements the C function
AAA_sayHi(const char *name)
. I can now create a C main file and compile it all together:main.c
Compiling it using a C compilation command:
I will need to set LD_LIBRARY_PATH to contain $PWD, and if I run the executable ./c_aaa, I will get the output I expect:
EDIT:
On some linux distributions,
-laaa
and-lstdc++
may also be required for the last compilation command. Thanks to @AlaaM. for the attention假设 C++ API 与 C 兼容(没有类、模板等),您可以将其包装在
extern "C" { ... }
中,就像采用其他方式时所做的那样。如果你想公开对象和其他可爱的 C++ 东西,你必须编写一个包装器 API。
Assuming the C++ API is C-compatible (no classes, templates, etc.), you can wrap it in
extern "C" { ... }
, just as you did when going the other way.If you want to expose objects and other cute C++ stuff, you'll have to write a wrapper API.
如果你想这样做,你必须用 C++ 编写 C 的包装器。 C++ 向后兼容,但 C 不向前兼容。
You will have to write a wrapper for C in C++ if you want to do this. C++ is backwards compatible, but C is not forwards compatible.