运行下面这段代码,就会提示:段错误。
typedef int (*dl_ImageDirCtrl)(unsigned char ucMirrorSet);
dl_AllLedCtrl *pFunc1;
fHandle=dlopen("../drvlib/libdrv.so",RTLD_LAZY);
if(fHandle==NULL)
{
printf("Load drvlib.so failed!/n");
fprintf (stderr, "%s/n", dlerror());
return -1;
}
else
printf("Load drvlib.so successfully!/n");
dlerror(); //Clear any existing error
pFunc1=(dl_AllLedCtrl *)dlsym(fHandle,"DrvLib_AllLedCtrl");
error = dlerror();
if(error!=NULL)
printf("Load Func from drvlib.so failed!Error is:%s/n",error);
else
(*pFunc1)(0);
什么是段错误呢? 其实质上就是函数指针跑飞了,指向的并不是一个合法的函数地址。
可上面的代码看上去是没有问题的呀?问题究竟出在什么地方呢?
原因在于对typedef int (*dl_ImageDirCtrl)(unsigned char ucMirrorSet);理解不深刻。
这个宏定义了一个类型,就象typedef UINT16 unsigned short一样。UINT16就可以用来修饰一个变量了。而dl_ImageDirCtrl就可以用来修饰一个函数指针变量。因此,dl_AllLedCtrl *pFunc1定义了一个指针,这个指针指向dl_AllLedCtrl类型的函数指针变量。所以,pFunc1=(dl_AllLedCtrl *)dlsym(fHandle,"DrvLib_AllLedCtrl");是不对的,应该是*pFunc1=(dl_AllLedCtrl *)dlsym(fHandle,"DrvLib_AllLedCtrl");但这样居然也是错误的。正确的写法是:
dl_AllLedCtrl *pFunc1; 修改为: dl_AllLedCtrl pFunc1;
pFunc1=(dl_AllLedCtrl *)dlsym(fHandle,"DrvLib_AllLedCtrl");改为:
pFunc1=(dl_AllLedCtrl )dlsym(fHandle,"DrvLib_AllLedCtrl");
(*pFunc1)(0);改为: (pFunc1)(0);
这样就可以了。
我记得windowx平台上面使用dll时,也有同样的现象。