问题
After trying to replace the offset keyword with __offsetof while trying to compile with Apple GCC 4.2.1 using the -fasm-blocks argument (which enables Intel style assembly syntax) inline assembly code which worked in MSVC, I get an error: Cannot apply offsetof to member function MyClass::MyFunction
class MyClass
{
void MyFunction(void* pData)
{
}
};
void test()
{
_asm
{
//mov eax, offset MyClass::MyFunction - this works in MSVC
mov eax, offsetof(class MyClass, MyFunction) //error: Cannot apply offsetof to member function MyClass::MyFunction
mov eax, __offsetof(class MyClass, MyFunction) //error: Invalid cast from type 'void (MyClass::*)(void*)' to type size_t
};
}
Can somebody please tell me, what should I do? It seems that the whole structure of the application I'm porting is based on this damn offset macro...
回答1:
offsetof
gets the offset of a member from the start of a structure, but functions are not members in that sense (not even virtual functions). what you are probably after is the offset
keyword:
class A
{
int Func1()
{
return 1;
}
};
__declspec(naked) int GetAddress()
{
__asm
{
mov eax, offset A::Func1
retn
}
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("0x%08X\n",GetAddress());
return 0;
}
To get the same effect under GCC (I'm using -masm=intel, as -fasm-blocks is apple only) we would do (32bit exe, tested under windows 7 64bit, using GCC 4.4):
class A
{
public:
int Func1() __attribute__((noinline))
{
return 1;
}
};
int a = 0; //this is bad, but it works for this demo
int GetAddress()// __attribute__((noinline))
{
__asm("mov dword ptr[_a], offset __ZN1A5Func1Ev");
return a;
}
int main()
{
A a;
printf("%d\n",a.Func1());
system("pause");
printf("0x%08X\n",GetAddress());
return 0;
}
The problem with GCC is that:
- you can't bind to auto-inlined functions, as no symbol is generated (hence the noinline).
- you need to bind to decorated symbols unless you force undecorated symbols (and even then there will still be some decoration)
回答2:
Try this:
mov eax, MyClass::MyFunction
What does it say?
PS: In old Intel syntax, this would have to be something like
mov eax, DWORD PTR MyClass::MyFunction
I don't know whether the gcc asm-block feature requires this or not.
回答3:
Since you said you don't need to hardcode it, just fetch the address in C++ code:
void test(){
typedef void (MyClass::*memfun)(void*);
memfun f = &MyClass::MyFunction;
__asm{
// I don't know why lea, but all forms of mov where failing. :|
lea eax, dword ptr [x];
call dword ptr [eax]; // test call, if the jump succeeds, you're done. :)
}
}
回答4:
You cannot use offsetof with member functions, only with data members. It makes no sense. Member functions are not actually stored in the class.
来源:https://stackoverflow.com/questions/6227256/gcc-error-cannot-apply-offsetof-to-member-function-myclassmyfunction