2017-09-05 20 views
1

这是C中的一种独特情况。覆盖函数指针的实现并用于共享库

说我们图书馆称为libfoo.solibbar.so,并在这两个我们同样的功能名称,Get_A,假设Get_A由系统调用。

libbar被加载,然后用参数G调用它的Get_AG是一些函数指针一个结构,有感兴趣的一个:

(*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打电话给我的包装功能。

回答

2

所以,当你做了直接赋值,你可能试图给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)

+0

嗯,这样做给我一个seg故障。 –

+0

您是否100%确定您要替换的功能提供了所有相同的功能?你不能用你自己的库来替换一个库函数,只是因为签名匹配期望它是花哨的。 –

+0

签名是正确的,什么可能是错误的,我可以从哪里开始寻找线索或寻找。 AFAIK我的事情是正确的。 –