在VS2008中访问void *的内容时,如何克服“错误C2100:非法间接”

时间:2008-10-14 22:13:36

标签: c visual-studio-2008

我有一个我在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位长?

4 个答案:

答案 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(如果有的话)将保留最多指针类型(我认为它不一定足以容纳一些指向成员的类型)。