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

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"<        else

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

 

添加依赖库

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

 

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

LD_DEBUG=libs  so名字

 

 

你可能感兴趣的:(C++,so,linux)