由于动态链接库在保持接口不变的前提下,可以独立更新,符合模块化开发的思想,而且.so可以通过回调函数的形式,对主程序进行异步的通知,所以在中型的c/c++项目中,编写so是一个不错的选择。
so的示例代码如下,PrintHello.cpp:
#include <iostream>
using namespace std;
// 将函数名作为指针的格式为:int (*ptr)(char *str) 即:返回值(指针名)(参数列表)
typedef int (*func)(const char *str); // 回调函数的名称为 fuc,参数是const char *str
void printHello()
{
cout<<"print hello update"<<endl;
}
void callBack(func notifyMain)
{
int ret = notifyMain("hahaha");
cout<<"main callback ret: "<<ret<<endl;
}
定义了2个函数,分别是直接处理和带回调的处理,其中回调函数通过typedef来定义,这样看起来比较直观,也可以直接用 int (*p)的形式来写。
编译方法:
g++ PrintHello.cpp -shared -fPIC -o libprinthello.so
主程序的接口文件 Interface.h:
typedef int (*func)(const char *str); // 回调函数的名称为 callback,参数是char *p
void printHello();
void callBack(func f);
接口文件定义主程序需要调用的so中的方法名称。
主程序 Main.cpp
#include <iostream>
#include "Interface.h"
using namespace std;
int ShowMsg(const char *str)
{
cout<<"main Show CallBack Info "<<str<<endl;
return 1;
}
int main()
{
cout<<"in main hello"<<endl;
printHello();
callBack(ShowMsg);
return 1;
}
编译的方法为,其中必须指定大写的L,否则小写的l会报错:
g++ Main.cpp Interface.h -L./ -lprinthello -o main
将生成文件main和libprinthello.so放到一个目录下,就可以运行了。
更新PrintHello.cpp的方法内容,只要不改变接口,都不影响main的运行,实现了模块化。