我有一个我在VS2008中创建的C应用程序。我正在创建一个模拟创建函数,它覆盖结构中的函数引用。但是,如果我尝试用以下方式直接进行此操作:
void *ptr = &(*env)->GetVersion;
*ptr = <address of new function>
然后我得到一个“错误C2100:非法间接”错误为* ptr,当ptr是一个void *似乎是一个禁止的构造。我可以通过使用int / long指针来解决它,将其映射到同一地址并修改长指针的内容:
*structOffsetPointer = &(*env)->GetVersion;
functionPointer = thisGetVersion;
structOffsetPointerAsLong = (long *)structOffsetPointer;
*structOffsetPointerAsLong = (long)functionPointer;
但我担心如果在32位和64位环境之间切换,使用long或int指针会导致问题。
那么有没有简单的方法来禁用此错误?假设没有,在win64下是int还是64位长?
答案 0 :(得分:4)
当解除引用“void *”时,你会留下一个没有大小的“void”(或者实际上没有类型),因此它不知道如何为它分配内容。它与:
相同void blah = 0xdeadbabe; // let's assume a 32-bit addressing system
要添加到我自己的响应并给出解决方案,我会给它一个指向GetVersion类型函数的正确类型的指针。如果你的“env”结构字段指向的GetVersion是:
int GetVersion();
然后你想要:
int (**ptr)() = &(*env)->GetVersion;
答案 1 :(得分:3)
那怎么样:
void **ptr = (void **) &(*env)->GetVersion;
*ptr = <address of new function>
执行此操作的正确方法是使用类型系统,避免所有转换并声明实际指针,如:
typedef int (*fncPtr)(void);
fncPtr *ptr = &(*env)->GetVersion;
*ptr = NewFunction;
以上假设GetVersion的类型为fncPtr,NewFunction的声明为 int NewFunction(void);
答案 2 :(得分:1)
上次我玩无效*&amp;在视觉工作室的C下,VS并没有很好地发挥。 以下是一些信息数据点:
指针始终是系统字的大小(8/16/32/64)...(除非你有分段内存,我假设你没有) 。这是因为它需要指向内存空间中的任何位置。对于 von Neumann 机器,函数指针的大小与数据指针的大小相同,因为数据和代码占用相同的内存空间。在 Harvard 架构下无法保证这一点。我对Windows Vista不太熟悉,知道它是否出于安全原因以编程方式伪造出哈佛架构。
我个人会不禁用此错误,只是为了让编译器完成其工作。
答案 3 :(得分:1)
如上所述,要将函数的地址存储在指针中,您就不应该执行间接操作。
但是,您还要谈论担心可能存储指针的int类型的大小(除非您有充分的理由,否则通常不是您想要做的事情)。
如果由于某种原因想要在int类型中保存指针,那么在Windows上UINT_PTR
类型(或uintptr_t
来自stdint.h
(如果有的话)将保留最多指针类型(我认为它不一定足以容纳一些指向成员的类型)。