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

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

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

C调用C++的静态库

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

内层 test.h
#pragma once

#include <string>

class Test
{
public:
    Test(std::string name) : name_(name) {}

    void name();

private:
    std::string name_;
};
内层 test.cpp
#include <iostream>
#include <stdio.h>

using namespace std;

#include "test.h"

void Test::name()
{
    cout << "My name is " << name_ << "!\n";
}
编译成静态库 libtest.a
g++ -c test.cpp   (如果你还依赖其他的第三方库比如opencv 需要在后面再链接 -lopencv_xx 同时你需要指定opencv库函数所在的头文件路径 (-I路径)和需要链接的静态库或动态库路径(-L路径))
ar -r libtest.a test.o

(如果你是在板端开发,需要用到交叉编译工具链来编译,如:aarch64-mix210-linux-gcc)
外层 test_c_api.h
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

void test_name(const char *name);

#ifdef __cplusplus
}
#endif
外层 test_c_api.cpp
#include "test_c_api.h"
#include "test.h"

#ifdef __cplusplus
extern "C" {
#endif

void test_name(const char *name)
{
    Test test(name);
    test.name();
}

#ifdef __cplusplus
}
#endif
编译外层静态库libtest_c_api.a
g++ -c test_c_api.cpp   (如果你还依赖其他的第三方库比如opencv 需要在后面再链接 -lopencv_xx 同时你需要指定opencv库函数所在的头文件路径 (-I路径)和需要链接的静态库或动态库路径(-L路径))
ar -r libtest_c_api.a test_c_api.o

(如果你是在板端开发,需要用到交叉编译工具链来编译,如:aarch64-mix210-linux-gcc)
main.c
#include "test_c_api.h"
#include <stdio.h>

int main()
{
  test_name("fang");
  return 0;
}
编译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)

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值