【发布时间】:2014-12-25 14:59:40
【问题描述】:
我试图编写一个共享库打开和函数调用的基本示例以进行练习,但事实证明,当可执行文件实际运行时,我总是遇到“分段错误”。以下是源代码:
main.cpp:
#include<iostream>
#include<dlfcn.h>
using namespace std;
typedef void (*API)(unsigned int);
int main(int argc,char** argv){
void* dl;
API api;
unsigned int tmp;
//...
dl=dlopen("pluginA.so",RTLD_LAZY);
api=(API)dlsym(dl,"API");
cin>>tmp;
(*api)(tmp);
dlclose(dl);
//...
return 0;
}
插件A.cpp:
#include<iostream>
using namespace std;
extern "C" void API(unsigned int N){switch(N){
case 0:cout<<"1\n"<<flush;break;
case 1:cout<<"2\n"<<flush;break;
case 2:cout<<"4\n"<<flush;break;
case 4:cout<<"16\n"<<flush;break;}}
我用以下命令编译了这两部分:
g++ -shared -o pluginA.so -fPIC plugin.cpp
g++ main.cpp -ldl
这是输出
Segmentation fault (core dumped)
顺便说一句,我也尝试直接调用 api(tmp) 而不是 (*api)(tmp),这也不起作用。既然api是指针,(*api)就更有意义了?
我不确定我应该怎么做。网上有很多关于共享库中调用函数的教程,但大部分都没有完全编码,或者实际上不起作用。
而且我也不确定我应该如何处理“attribute((visibility("default")))”。我应该把它写下来吗?
EDT1 谢谢你给我这么多建议。终于发现其实一切都是编译命令的错别字……我把pluginA.so误打成了pluginA.o,这就是它不起作用的原因……
无论如何,这是我修改后的程序,添加了错误处理,并添加了更“完整”的系统:
main.cpp:
#include<dirent.h>
#include<dlfcn.h>
#include<iostream>
#include<cstring>
using namespace std;
typedef bool (*DLAPI)(unsigned int);
int main(){
DIR* dldir=opendir("dl");
struct dirent* dldirf;
void* dl[255];
DLAPI dlapi[255];
unsigned char i,dlc=0;
char dldirfname[255]="./dl/";
unsigned int n;
while((dldirf=readdir(dldir))!=NULL){
if(dldirf->d_name[0]=='.')continue;
strcat(dldirfname,dldirf->d_name);
dl[dlc]=dlopen(dldirfname,RTLD_LAZY);
if(!dl[dlc])cout<<dlerror()<<endl;else{
dlapi[dlc]=(DLAPI)dlsym(dl[dlc],"API");
if(!dlapi[dlc])cout<<dlerror()<<endl;else dlc++;}
dldirfname[5]='\0';}
if(dlc==0){
cerr<<"ERROR:NO DL LOADED"<<endl;
return -1;}
while(true){
cin>>n;
for(i=0;i<dlc;i++)if((*dlapi[i])(n))break;
if(i==dlc)cout<<"NOT FOUND"<<endl;}
for(i=0;i<dlc;i++)dlclose(dl[i]);
return 0;}
【问题讨论】: