一、生成SO文件
#include <iostream>
using namespace std;
#ifdef __cplusplus
extern "C"
{
#endif
int CnToNum(const char* pszString,long long* pnNum);
#ifdef __cplusplus
}
#endif
需要注意的是:extern "C"修饰符,如果缺少此符号,则在使用dlsym时无法定位函数入口,导致dlsym返回0值。
生成包含文件SoTest.cpp,代码如下:
#include "SoTest.h"#include <stdlib.h>
int CnToNum(const char* pszString,long long* pnNum)
{
*pnNum = atol(pszString);
return *pnNum;
}
代码实现很简单,无须赘述。
使用下列命令,生成动态库文件(so):
g++ -shared -fPIC SoTest.cpp -o libSoTest.so
二、编写静态链接测试程序
编写静态链接测试程序(SoTestStatic.cpp)
#include "SoTest.h"
#include <iostream>
using namespace std;
int main()
{
long long nNum = 0;
cout << CnToNum("123",&nNum) << endl;
cout << nNum << endl;
return 0;
}
执行如下命令生成二进制文件:
g++ SoTestStatic.cpp -o SoTestStatic -L. -lSoTest
将libSoTest.so文件复制到目录/usr/lib中,再运行
./SoTestStatic
即可正常显示。
三、编写动态链接测试程序
编写动态链接测试程序(SoTestDynamic.cpp)#include <iostream>
#include <dlfcn.h>
using namespace std;
typedef int (*TCnToNum)(const char*,long long*);
int main()
{
void* dll = NULL;
dll = dlopen("libSoTest.so",RTLD_NOW);
if(dll == NULL)
{
cout << "open libSoTest.so error " << endl;
return -1;
}
TCnToNum f = (TCnToNum)dlsym(dll,"CnToNum");
long long nNum = 0;
cout << f("555",&nNum) << endl;
cout << nNum << endl;
dlclose(dll);
return 0;
}
执行如下命令,生成二进制代码:
g++ SoTestDynamic.cpp -o SoTestDynamic -g -ldl
将libSoTest.so文件复制到目录/usr/lib中,再运行
./SoTestDynamic
即可正常显示。
四、动态链接与静态链接的区别
(1):静态链接依赖于包含文件(SoTest.h),而动态链接不需要此文件,只要知道函数的声明格式即可,本例中定义了这样的一个类型:typedef int (*TCnToNum)(const char*,long long*);
(2):生成二进制的方法不同,静态链接方式依赖于库文件(libSoTest.so)文件,而动态链接直接加载动态库;
(3):使用的函数个数也不相同,静态链接只有一个函数即可实现对共享库的使用;而动态链接方式则需要额外的加载(dlopen)、卸载(dlclose)及函数定位(dlsym)才可以实现对函数的使用;
(4):生成二进制的命令不同,静态链接方式依赖于libSoTest.so文件,动态链接则不需要此文件。