Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I overcome the "error C2100: illegal indirection" when accessing the contents of a void* in VS2008

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?

like image 558
David Arno Avatar asked Dec 30 '22 09:12

David Arno


2 Answers

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);

like image 168
Tony Lee Avatar answered Jan 01 '23 23:01

Tony Lee


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;
like image 29
Jim Buck Avatar answered Jan 01 '23 23:01

Jim Buck