将编写的C++文件在linux下编写so文件,添加依赖库so

    xiaoxiao2021-03-25  22

    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<iostream> using namespace std; int Test::hello(int i){        if(i>3)

                     cout<<"hello Class Test>3"<<endl;        else

                      cout<<"hello Class Test<3"<<endl;         return 0; } 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等进行控制平台的类型。

     

    添加依赖库

    使用VS2015中的linux插件进行编写so库的时候,和编写dll一样,需要制定so库对外的接口的.h文件,的路径,指定Linker中的依赖库的在linux上的路径,和Library dependencies,这里依赖库的名字要将前边的“lib“去掉,将“.so“去掉;之后进行编译就可以了,这时可以编译成功但是在linux使用  ldd *.so的时候,发现有的依赖库找不到,这就需要在.bash_profile中添加依赖库的路径,之后,source .bash_profile就可以了。

     

    20190920:查看某个库中依赖的so的路径和对应的so

    LD_DEBUG=libs  so名字

     

     

    转载请注明原文地址: https://ju.6miu.com/read-50195.html

    最新回复(0)