前言:从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命令就行。)