覆盖函数指针的实现并用于共享库
这是C
中的一种独特情况。覆盖函数指针的实现并用于共享库
说我们图书馆称为libfoo.so
和libbar.so
,并在这两个我们同样的功能名称,Get_A
,假设Get_A
由系统调用。
说libbar
被加载,然后用参数G
调用它的Get_A
。 G
是一些函数指针一个结构,有感兴趣的一个:
(*G)->RegisterBaz
所以libbar
的调用Get_A
,我们要变异的指针,RegisterBaz函数,然后调用libfoo
'的S版Get_A
借助于dlopen + dlsym。
有一两件事我想直接分配,但后来我的一个编译器错误只读变量无法分配的,所以我试图去通过指针:
// not void * but actually some function signature typedefed.
void *f_ptr = (*G)->RegisterBaz;
*&f_ptr = r_n;
凡r_n
是一个普通的C函数具有相同签名RegisterBaz
和r_n
我叫原来实行的RegisterBaz
因此,虽然这并不赛格故障,它不带d打电话给我的包装功能。
所以,当你做了直接赋值,你可能试图给const函数指针分配一个函数;这显然不是你能做的事情。
此外,在代码:
void *f_ptr = (*G)->RegisterBaz;
*&f_ptr = r_n;
实际上
,f_ptr
指向(*G)->RegisterBaz
正指向同样的事情,所以,当你改变f_ptr
与*&
(基本无操作)你是不是完全没有修改(*G)->RegisterBaz
。
另外,您不能将函数指针分配给对象指针; void *
类型的东西只能保证能够保存对象指针。 (INCITS-ISO-IEC 9899-2011 6.3.2.3p7)
所以,如果出于某种原因,你死心塌地改变(*G)->RegisterBaz
直接,你可以这样做:
void (**f_ptr)(void) = (void (**)(void))&((*G)->RegisterBaz);
*f_ptr = r_n;
但因为你将要通过(*G)->RegisterBaz
调用,您需要确保替换函数签名与(*G)->RegisterBaz
碰巧指向的函数签名相匹配。
除非f_ptr
的类型为指针指向"insert signature of called function here"
,否则您也会收到警告。
我需要重申这不是你通常想要做的事情,所以我不能保证这将起作用。但是,如果你死定了它,这是你将如何做到这一点(基本上你是const的const函数指针别名非const)
嗯,这样做给我一个seg故障。 –
您是否100%确定您要替换的功能提供了所有相同的功能?你不能用你自己的库来替换一个库函数,只是因为签名匹配期望它是花哨的。 –
签名是正确的,什么可能是错误的,我可以从哪里开始寻找线索或寻找。 AFAIK我的事情是正确的。 –