1,需要的头文件和cpp 文件
==========test.h===========
#ifdef __cplusplus // 注意,这里是双下划线!!!
extern "C"
{
#endif
class Test{ //有类写类,没有就不写了
public:
int hello(int i);
};
int helloT(int j);
#ifdef __cplusplus
}
#endif
==========test.cpp=========== 这里是你的cpp文件,需要执行的文件
#include"test.h"
#include
using namespace std;
int Test::hello(int i){
if(i>3)
cout<<"hello Class Test>3"<
cout<<"hello Class Test<3"<
}
int helloT(int j){
Test *t=new Test();
t->hello(j);
return 0;
}
编译test.cpp文件
g++ -shared -fpic -lm -ldl -o libtest.so test.cpp
( g++ -shared -fpic -lm -ldl -lstdc++ -o libwavelet2d.so wavelet2d.cpp 这里添加了-lstdc++用来连接C++的头文件中添加的库)
编写debug版本的so文件同时显示错误行号和函数
g++ -shared -Ddebug -g -rdynamic -fpic -lm -ldl -o libFilterDll.so FilterDLL.cp
其中-Ddebug :将文件编译成
其中,so文件名必须以lib开头。编译具体指令请参考帮助文档
在进行编写含有shared_ptr的智能指针的时候,要在其中加上 -std=c++11 才可以将程序编译通过。
2,到这里基本就能得到需要的so文件了,但是注意其中的文件的名称就可以了。
3,(测试用的)如果编译出错,就要进行测试了,写一个main文件,将.h文件加载在头文件中,写一个测试程序,将变量配置好文件就可以了;在进行编译的命令是:
gcc -o test main.cpp -L. -lwavelet2d -lstdc++
gcc -ggdb3 -Wall -o test main.cpp -L. -lwavelet2d -lstdc++
在下面有一个相似流程的文件, 这里的不同之处就是为了防止C++库不能加载,添加了 -lstdc++命令。
4,修改环境变量:修改LD_LIBRARY_PATH变量,加上库所在的目录,这里是当前目录
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
5,查看生成的so文件,查看其中的函数; nm -D *.so 或者使用$ nm *.so |grep 函数名; 有时看到需要的文件中的外部调用的函数前面有乱码,注意的 是:在编写#ifdef __cplusplus // 注意,这里是双下划线!!!
6,ldd *.so用来查看生成的.so文件中,其中的文件都是可用的。
添加:在linux下编写debug版本的文件:命令:
g++ -ggdb3 -Wall -shared -fpic -lm -ldl -lstdc++ -o libyocalyecg.so Resample.cpp EcgLib.cpp
学习小知识:
1,查看linux系统 是32位还是64位:使用getconf LONG_BIT 就可以显示系统是32还是64位的烯烃
2,uname:命令查看系统的是32还是64位系统。 -a比较全,-m较为简短。
3,arch :也可以查看;file /sbin/init 也可以i显示。
控制编写的so是32位还是64位:
1,objdump -a *.a objdump -a *.so
9-12添加,区分不同的平台
#ifdef _WIN32
extern "C"
{
__declspec(dllexport) int _stdcall QRS_detect_sample(int*buff, const int buf_size, const int fs, int MA_ord_qrs, int N_qrs, int N_RR, int *QRS, int *QRS_len, float * SNR);
__declspec(dllexport) int _stdcall QRS_detect_sample16(short*buff, const int buf_size, const int fs, int MA_ord_qrs, int N_qrs, int N_RR, int *QRS, int *QRS_len, float * SNR);
__declspec(dllexport) int _stdcall QRS_detect_millivolt(float *buff, const int buf_size, const int fs, int MA_ord_qrs, int N_qrs, int N_RR, int *QRS, int *QRS_len, float * SNR);
}
#else
#ifdef __cplusplus
extern "C"
{
#endif
int QRS_detect_sample(int*buff, const int buf_size, const int fs, int MA_ord_qrs, int N_qrs, int N_RR, int *QRS, int *QRS_len, float * SNR);
int QRS_detect_sample16(short*buff, const int buf_size, const int fs, int MA_ord_qrs, int N_qrs, int N_RR, int *QRS, int *QRS_len, float * SNR);
int QRS_detect_millivolt(float *buff, const int buf_size, const int fs, int MA_ord_qrs, int N_qrs, int N_RR, int *QRS, int *QRS_len, float * SNR);
#ifdef __cplusplus
}
#endif
#endif
2)使用vs编写so,其中也要给开头写对外的接口,这和其他的编写方式是一样的。
3)在VS 上编写so文件,可以接引用编写dll的程序(就是将需要的文件通过添加现有项,将文件添加进当前的项目中),然后将其中的一些不需要的文件通过平台选择注释掉:
例如:上面的编译接口的方式,通过ifdef等进行控制平台的类型。
20190920:查看某个库中依赖的so的路径和对应的so
LD_DEBUG=libs so名字