当前位置:   article > 正文

如何从C中调用C++函数_c调用cpp函数

c调用cpp函数

前言:从C++中调用C的函数很简单,只需要加 extern “C” 就行,但是在C中调用C++函数就会复杂很多,毕竟C++能兼容C,但是反过来就不行。

推荐使用静态库,在板端用动态库使用有些问题,还没测试成功

C调用C++的静态库

.c 程序无法直接调用 .cpp 的函数,但是我们可以采用嵌套包裹的形式来实现,用外层包裹函数去包裹内层cpp函数,外层的包裹函数虽然是cpp,但是用C的规则进行编写,这样 .c 程序就可以调用这个包裹函数了。

内层 test.h
  1. #pragma once
  2. #include <string>
  3. class Test
  4. {
  5. public:
  6. Test(std::string name) : name_(name) {}
  7. void name();
  8. private:
  9. std::string name_;
  10. };
内层 test.cpp
  1. #include <iostream>
  2. #include <stdio.h>
  3. using namespace std;
  4. #include "test.h"
  5. void Test::name()
  6. {
  7. cout << "My name is " << name_ << "!\n";
  8. }
编译成静态库 libtest.a
  1. g++ -c test.cpp (如果你还依赖其他的第三方库比如opencv 需要在后面再链接 -lopencv_xx 同时你需要指定opencv库函数所在的头文件路径 (-I路径)和需要链接的静态库或动态库路径(-L路径))
  2. ar -r libtest.a test.o
  3. (如果你是在板端开发,需要用到交叉编译工具链来编译,如:aarch64-mix210-linux-gcc)
外层 test_c_api.h
  1. #pragma once
  2. #ifdef __cplusplus
  3. extern "C" {
  4. #endif
  5. void test_name(const char *name);
  6. #ifdef __cplusplus
  7. }
  8. #endif
外层 test_c_api.cpp
  1. #include "test_c_api.h"
  2. #include "test.h"
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. void test_name(const char *name)
  7. {
  8. Test test(name);
  9. test.name();
  10. }
  11. #ifdef __cplusplus
  12. }
  13. #endif
编译外层静态库libtest_c_api.a
  1. g++ -c test_c_api.cpp (如果你还依赖其他的第三方库比如opencv 需要在后面再链接 -lopencv_xx 同时你需要指定opencv库函数所在的头文件路径 (-I路径)和需要链接的静态库或动态库路径(-L路径))
  2. ar -r libtest_c_api.a test_c_api.o
  3. (如果你是在板端开发,需要用到交叉编译工具链来编译,如:aarch64-mix210-linux-gcc)
main.c
  1. #include "test_c_api.h"
  2. #include <stdio.h>
  3. int main()
  4. {
  5. test_name("fang");
  6. return 0;
  7. }
编译main生成可执行文件,同时指定需要链接的静态库 libtest.a 和 libtest_c_api.a
gcc -o main main.c -L. -ltest -ltest_c_api
这里再解释下 目标文件.o  静态库文件.a  动态库文件.so

.o 称为目标文件,是源代码编译之后产生的二进制代码。

.a 是静态库,这个东西和.o的关系其实很清楚,基本上就是.o打了一个包,把多个.o文件放到一个.a文件里面。所以你标题里的一个问题 .o能不能放进.a?答案是能,而且大家一般就是这样子生成.a的。

.so是动态库。为了讲清楚动态库,咱们来看看静态库,假设你编了程序a.out,如果它链接了一个静态库libxx.a那么a.out这个文件里面直接包含了从libxx.a里面来的所有有用的数据。这是静态库的含义,在链接时直接合并到了可执行文件之中。而动态库则相反,如果你的程序链接了libyy.so,那么libyy.so里面的代码并没有合并到a.out之中,而在a.out真正被执行的时候,加载器才会从你的机器上找到libyy.so,把它加载到你的程序的地址空间里面以便于你能够使用其中的函数。

这里有个比较常见的问题就是.so可以一起包含进.a吗

如果你的.a依赖于一个.so,那么你没必要把.so加到.a里(也不能像.o一样直接加进去,他们文件格式不一样)。你就直接编出来一个.a就行,等到后面要编可执行文件时再把你的.a链进来并且指定这个文件要链接你的.so库(用gcc 的 -L/path/to/dir -lyy命令就行。)

相关文章阅读

C调用C++库和C++调用C库的方法_c++ 调用c库_码农小明的博客-CSDN博客

如何从C中调用C++函数 - 知乎 (zhihu.com)

(1 封私信) .so和.o可以一起被包含进.a吗? - 知乎 (zhihu.com)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/194924
推荐阅读
相关标签
  

闽ICP备14008679号