Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 重写函数指针的实现并用于共享库_C_Pointers_Dll - Fatal编程技术网

C 重写函数指针的实现并用于共享库

C 重写函数指针的实现并用于共享库,c,pointers,dll,C,Pointers,Dll,这在C中是一种独特的情况 假设我们有一个名为libfoo.so和libbar.so的库,在这两个库中,我们使用相同的函数名,Get_a,假设系统调用了Get_a 假设加载了libbar,然后使用参数G调用其Get\u AG是一个带有一些函数指针的结构,其中一个是: (*G)->寄存器baz 因此,在libbar调用Get_A时,我们希望变异指向该RegisterBaz函数的指针,然后通过dlopen+dlsym调用libfoo版本的Get_A 我尝试过的一件事是直接赋值,但后来我得到了一个编译器

这在
C
中是一种独特的情况

假设我们有一个名为
libfoo.so
libbar.so
的库,在这两个库中,我们使用相同的函数名,
Get_a
,假设系统调用了
Get_a

假设加载了
libbar
,然后使用参数
G
调用其
Get\u A
G
是一个带有一些函数指针的结构,其中一个是:

(*G)->寄存器baz

因此,在
libbar
调用
Get_A
时,我们希望变异指向该RegisterBaz函数的指针,然后通过dlopen+dlsym调用
libfoo
版本的
Get_A

我尝试过的一件事是直接赋值,但后来我得到了一个编译器错误,只读变量是不可赋值的,所以我尝试通过指针:

// not void * but actually some function signature typedefed.
void *f_ptr = (*G)->RegisterBaz;
*&f_ptr = r_n;
其中,
r\u n
是一个普通的C函数,其签名与
RegisterBaz

r\u n
中,我调用了
RegisterBaz


因此,虽然这并没有seg错误,但它也不会最终调用我的包装函数

因此,当您执行直接赋值时,您可能试图将函数赋值给常量函数指针;这显然不是你能做的

此外,在守则中:

void *f_ptr = (*G)->RegisterBaz;
*&f_ptr = r_n;
实际上,
f_ptr
指向的是与
(*G)->RegisterBaz
指向的相同的东西,因此当您使用
*&
更改
f_ptr
时(基本上是一个无操作),您根本没有修改
(*G)->RegisterBaz

此外,不能将函数指针分配给对象指针;
void*
类型的东西只能保证能够保存对象指针。(INCITS-ISO-IEC 9899-2011)

因此,无论出于何种原因,如果您执意要直接更改
(*G)->RegisterBaz
,您可以执行以下操作:

void (**f_ptr)(void) = (void (**)(void))&((*G)->RegisterBaz);
*f_ptr = r_n;
但由于您将通过
(*G)->RegisterBaz
调用,因此需要确保替换函数签名与
(*G)->RegisterBaz
恰好指向的函数签名匹配

除非
f_ptr
类型为指针指向
“在此处插入被调用函数的签名”
,否则您还会收到警告


我需要重申这不是你通常想要做的事情,所以我不能保证这会起作用。但是,如果你一意孤行,你会这么做(基本上你是将常量函数指针别名为非常量指针。)

Hmm,这样做会给我一个seg错误。你100%确定你要替换的函数提供了所有相同的功能吗?你不能仅仅用你自己的函数替换一个库函数,并且仅仅因为签名匹配就期望它是漂亮的。签名是正确的,有什么可能是错误的,我可以从哪里开始寻找线索或查找。很抱歉,我忘记了一个&,所以请尝试使用我编辑的代码。不幸的是,仍然是seg错误,我在Android上这样做,所以也在寻找在命令行上查找lldb到应用程序的方法。