赞
踩
前言:从C++中调用C的函数很简单,只需要加 extern “C” 就行,但是在C中调用C++函数就会复杂很多,毕竟C++能兼容C,但是反过来就不行。
推荐使用静态库,在板端用动态库使用有些问题,还没测试成功
.c 程序无法直接调用 .cpp 的函数,但是我们可以采用嵌套包裹的形式来实现,用外层包裹函数去包裹内层cpp函数,外层的包裹函数虽然是cpp,但是用C的规则进行编写,这样 .c 程序就可以调用这个包裹函数了。
- #pragma once
-
- #include <string>
-
- class Test
- {
- public:
- Test(std::string name) : name_(name) {}
-
- void name();
-
- private:
- std::string name_;
- };
- #include <iostream>
- #include <stdio.h>
-
- using namespace std;
-
- #include "test.h"
-
- void Test::name()
- {
- cout << "My name is " << name_ << "!\n";
- }
- g++ -c test.cpp (如果你还依赖其他的第三方库比如opencv 需要在后面再链接 -lopencv_xx 同时你需要指定opencv库函数所在的头文件路径 (-I路径)和需要链接的静态库或动态库路径(-L路径))
- ar -r libtest.a test.o
-
- (如果你是在板端开发,需要用到交叉编译工具链来编译,如:aarch64-mix210-linux-gcc)
- #pragma once
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- void test_name(const char *name);
-
- #ifdef __cplusplus
- }
- #endif
- #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
- 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)
- #include "test_c_api.h"
- #include <stdio.h>
-
- int main()
- {
- test_name("fang");
- return 0;
- }
gcc -o main main.c -L. -ltest -ltest_c_api
.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,把它加载到你的程序的地址空间里面以便于你能够使用其中的函数。
如果你的.a依赖于一个.so,那么你没必要把.so加到.a里(也不能像.o一样直接加进去,他们文件格式不一样)。你就直接编出来一个.a就行,等到后面要编可执行文件时再把你的.a链进来并且指定这个文件要链接你的.so库(用gcc 的 -L/path/to/dir -lyy命令就行。)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。