she*_*lbc 12 c function-pointers dynamic-linking
我需要在运行时动态链接库并使用解析一系列函数dlsym.我的第一个想法是使用一个函数指针数组,通过利用char *表示符号名称的辅助数组,可以很容易地迭代.
但是,问题在于并非所有函数都使用相同的参数.有没有办法在数组中使用泛型函数指针,但是将它分配给限制性更强的函数指针原型?例如:
如果我需要解决这些功能:
int (*functionA)(int)
char (*functionB)(char,int)
Run Code Online (Sandbox Code Playgroud)
是否有可能做某些事情(伪似......)
void* functionList(...)[2] = {functionA, functionB};
Run Code Online (Sandbox Code Playgroud)
随着
char FuncNameA[] = "functionA";
char FuncNameB[] = "functionB";
char *functionNames[2] = {FuncNameA, FuncNameB};
Run Code Online (Sandbox Code Playgroud)
用于循环调用dlsym符号解析的目的
int i = 0;
for(; i<2; i++)
functionList[i] = dlsym(DL_OPEN_HANDLE, functionNames[i]);
Run Code Online (Sandbox Code Playgroud)
其中DL_OPEN_HANDLE将由之前的调用定义dlopen.
Kei*_*son 13
C标准保证可以在void*不丢失信息的情况下将任何对象指针类型转换为和返回(意味着重新转换的指针将与原始指针进行比较).
函数指针没有这样的保证.例如,一种实现可以使void*64位和函数指针成为128位.
但是任何函数指针都可以转换为任何其他函数指针类型,然后再返回而不会丢失信息.
例如,您可以使用void(*)(void)通用函数指针类型:
typedef void (*funcptr)(void);
Run Code Online (Sandbox Code Playgroud)
在执行调用之前,必须转换回原始指针类型以避免未定义的行为.
另一方面,你正在使用dlsym(),它返回一个void*.我的理解是POSIX保证void*返回的dlsym()(如果name参数名称函数)可以转换为函数指针,可以用来调用函数.如果您关心的唯一功能是那些返回地址的功能dlsym(),那么您可以使用void*.
(POSIX以前保证,作为C标准的扩展,函数指针可以转换为void*后退.后来保证了这个保证.感谢Jonathan Leffler指出这一点.)
在任何情况下,使用函数指针来存储函数的地址可能会使代码更清晰.
您可能应该将列表定义为void *functionList[2],因为dlsym返回 a void *。一旦知道了自己拥有哪个函数,就可以将其转换为正确的类型。
void *functionList[2];
...
int (*functionA)(int) = (int(*)(int))functionList[0];
char (*functionB)(char,int) = (char(*)(char, int))functionList[1];
Run Code Online (Sandbox Code Playgroud)
dlsym返回类型为 的数据指针void *,但 POSIX 保证可以将其转换为适当类型的函数指针:
支持 XSI 扩展的实现 [...] 要求该类型的对象
void *可以保存指向函数的指针。然而,将函数指针转换为另一种数据类型(除了void *)的指针的结果仍然是未定义的。
从 POSIX 版本 7 开始,所有实现(不仅仅是 XSI)都需要支持转换。
由于void *通过直接转换从指针到函数指针的转换可能会导致编译器警告,因此旧版本的 POSIX 建议通过别名执行转换:
int (*fptr)(int);
*(void **)(&fptr) = dlsym(handle, "my_function");
Run Code Online (Sandbox Code Playgroud)
在当前版本中,建议更改为:
int (*fptr)(int);
fptr = (int (*)(int))dlsym(handle, "my_function");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4544 次 |
| 最近记录: |