首先需要建立两个文件夹,一个存放C代码用来生成动态库.so, 命名为c_library;另一个用来写C++代码,调用C的动态库,命名为library_test。
-------c_library
------------build
------------print_test.c
------------print_test.h
------------print_test.hpp
-------library_test
------------build
------------print_test.h
------------print_test.hpp
------------use_cso.cc
接下来展示各个模块的代码
print_test.c
#include "print_test.h"
void CPrintTest(int *a){
*a = 5;
printf("run in PrintTest !! \n");
printf("stdio.a = %d \n", *a);
}
print_test.c 是c语言函数CPrintTest,作用是将a赋值为5。因为c语言没有C++取地址当形参的功能。所以只能用指针的形式改变传入参数的值。
print_test.h
#include "stdio.h"
#ifdef __cplusplus
extern "C" { // 告诉编译器下列代码要以C链接约定的模式进行链接
#endif
void CPrintTest(int *a);
#ifdef __cplusplus
}
#endif
print_test.h 是.c文件的头文件,需要加入extern C告诉编译器运行该段代码需要按C模式编译。
print_test.hpp
#include <iostream>
#include "print_test.h"
void CPrintTest(int *a);
hpp文件是C++特有的头文件形式,该hpp文件include了h文件,给上述C文件提供了个C++接口。意味着C++代码可以调用这个hpp文件实现C文件功能。
c_library cmakelists
cmake_minimum_required(VERSION 3.1)
project(c_library)
set(print_src print_test.c)
include_directories("${PROJECT_SOURCE_DIR}")
add_library( print_test SHARED ${print_src})
CMakeLists用add_library将C文件编译成libprint_test.so动态库
use_cso.cc
#include <iostream>
#include "print_test.hpp"
int main(){
int a = 0;
CPrintTest(&a);
std::cout << "std::a = " << a << std::endl;
}
将print_test.h和print_test.hpp和libprint_test.so三个文件一起放到library_test中,与use_cso.cc一起。use_cso.cc直接调用hpp文件即可。
library_test CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
project(library_test)
SET(CMAKE_CXX_COMPILER "g++")
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS} -O3 -Wall -lpthread -march=native")
add_executable(use_cso_test
use_cso.cc
)
target_link_libraries(use_cso_test
${PROJECT_SOURCE_DIR}/libprint_test.so
)
在library_test的cmakelists中 用target_link_libraries将so文件路径编译进可执行文件中。
最后执行 ./use_cso_test可执行文件可得 a = 5
整体流程就是 用hpp封装h,编译生成动态库so,给C++提供动态库so和hpp、h,就能实现c文件调用动态库的功能。
本文详细介绍了如何创建一个C语言函数并封装为动态库.so,然后在C++中通过.hpp文件调用这个动态库。整个过程包括C文件的编写、C++接口的封装、CMakeLists配置以及最终的执行示例,展示了C++如何与C动态库无缝对接。

被折叠的 条评论
为什么被折叠?



