问题
I have a C application that I've created in VS2008. I am creating a mock creation function that overrides function references in a struct. However if I try and do this in a straight forward fashion with something like:
void *ptr = &(*env)->GetVersion;
*ptr = <address of new function>
then I get a "error C2100: illegal indirection" error as *ptr, when ptr is a void * seems to be a banned construct. I can get around it by using a int/long pointer as well, mapping that to the same address and modifying the contents of the long pointer:
*structOffsetPointer = &(*env)->GetVersion;
functionPointer = thisGetVersion;
structOffsetPointerAsLong = (long *)structOffsetPointer;
*structOffsetPointerAsLong = (long)functionPointer;
but I am concerned that using long or int pointers will cause problems if I switch between 32 and 64 bit environments.
So is there are easy way to disable this error? Assuming not, is either int or long 64 bits under win64?
回答1:
Then how about:
void **ptr = (void **) &(*env)->GetVersion;
*ptr = <address of new function>
The right way to do this is to work with the type system, avoid all the casting and declare actual pointers to functions like:
typedef int (*fncPtr)(void);
fncPtr *ptr = &(*env)->GetVersion;
*ptr = NewFunction;
The above assumes GetVersion is of type fncPtr and NewFunction is declared as int NewFunction(void);
回答2:
When dereferencing a "void *", you are left with a "void" which is has no size (or really no type for that matter), so it doesn't know how to assign something to it. It is the same as:
void blah = 0xdeadbabe; // let's assume a 32-bit addressing system
To add to my own response and give a solution, I would give it the proper type of a pointer to a function of the type GetVersion is. If GetVersion that your "env" struct field is pointing to is:
int GetVersion();
then you want:
int (**ptr)() = &(*env)->GetVersion;
回答3:
Last time I played with void* & C under visual studio, VS didn't play nicely. Here are some information datapoints:
A pointer is always the size of the system word(8/16/32/64)...(unless you have segmented memory, which I'm assuming you don't have). This is because it needs to point to anywhere in the memory space. For a von Neumann machine, a function pointer is going to be the same size as a data pointer, because data and code occupy the same memory space. This is not guaranteed under a Harvard architecture. I'm not familiar enough with Windows Vista to know if it programatically fakes out a Harvard architecture for security reasons.
I personally would not disable this error, just for the sake of letting the compiler do its job.
回答4:
As mentioned, to store the address of a function in a pointer you should simply not do the indirection.
However, you also talk about being worried about the size of an int type that you might store a pointer into (which generally is not something you want to do unless you have a really good reason to).
If you want to hold a pointer in an int type for some reason, then on Windows a UINT_PTR type (or uintptr_t from stdint.h if you have it) will hold most pointer types (I don't think it's necessarily large enough to hold some pointer-to-member types).
来源:https://stackoverflow.com/questions/203058/how-can-i-overcome-the-error-c2100-illegal-indirection-when-accessing-the-con