如果动态链接库直接调用了静态库提供的函数,那么在生成动态库时需要静态链接被调用的函数。为了避免静态链接,可以调用函数指针而不是调用函数。原因在于:函数指针是一种变量,其值可以在运行时刻获得。
假设要编译生成testSo.So,testSo.so模块中需要调用A模块的函数func。
如果在testSo.so文件中直接调用A模块的func的函数,那么在编译生成testSo.so文件时肯需要静态链接库A模块。编写的代码如下:
//如下是testSo.so的源文件
int funInSo()
{
Int ret = func();//直接调用了A模块的func.
}
如果在testSo.so文件中使用的是函数指针而不是函数,那么则不需要静态链接A模块。代码例子为:
//如下是testSo.so的源文件
typedef int (*func)();
int funInSo()
{
//声明func类型的变量pFunc,并给变量pFunc赋值。
Int ret = pFunc();//使用了函数指针
}
使用函数指针避免静态链接的主要问题是:在动态库testSo中,如何正确的设置函数指针pFunc?
我给出如下一种参考方法:
第一, 动态链接库中的导出函数必须有如下的原型。
ReturnType functionName(FunctionTable*, …..); 或者
ReturnType functionName(FunctionPointer*, ….);
“…”省略号表示其他参数。 上述例子中的pFunc或者是参数FunctionPointer的值,或者作为方法表FunctionTable的成员变量。
第二, 有且仅有一个模块装载动态链接库/直接调用动态链接库的导出函数。此库名称假设为porting。
第三, Porting库调用导出函数时,将方法表指针或者函数指针作为实参传递给导出函数。
使用上述方法编译的动态链接库不需要静态链接,但要仔细考虑porting库如何实现。