C++ GCC错误:无法将offsetof应用于成员函数MyClass::MyFunction

C++ GCC错误:无法将offsetof应用于成员函数MyClass::MyFunction,c++,visual-c++,gcc,assembly,inline-assembly,C++,Visual C++,Gcc,Assembly,Inline Assembly,尝试使用在MSVC中工作的-fasm blocks参数(该参数启用英特尔风格汇编语法)使用AppleGCC 4.2.1编译内联汇编代码时,尝试将offset关键字替换为\uu offsetof,我收到一个错误:无法将offsetof应用于成员函数MyClass::MyFunction class MyClass { void MyFunction(void* pData) { } }; void test() { _asm { //mo

尝试使用在MSVC中工作的-fasm blocks参数(该参数启用英特尔风格汇编语法)使用AppleGCC 4.2.1编译内联汇编代码时,尝试将offset关键字替换为\uu offsetof,我收到一个错误:无法将offsetof应用于成员函数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
    };
}


谁能告诉我,我该怎么办?我移植的应用程序的整个结构似乎是基于这个该死的<强>偏移/强>宏…< /p> ,因为你说你不需要对它进行硬编码,只要用C++代码获取地址:

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. :)
  }
}

不能对成员函数使用offsetof,只能对数据成员使用offsetof。这毫无意义。成员函数实际上并不存储在类中。

offset of
获取成员从结构开始的偏移量,但函数在这个意义上不是成员(甚至不是虚拟函数)。您可能想要的是
offset
关键字:

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;
}
为了在GCC下获得相同的效果(我使用-masm=intel,因为-fasm块仅适用于apple),我们将执行以下操作(32位exe,在windows 7 64位下测试,使用GCC 4.4):

GCC的问题在于:

  • 您不能绑定到自动内联函数,因为没有生成符号(因此是noinline)
  • 您需要绑定到装饰符号,除非强制使用未装饰的符号(即使这样,仍会有一些装饰)
  • 试试这个:

    mov eax, MyClass::MyFunction
    
    上面说什么

    PS:在旧的英特尔语法中,这必须是

    mov eax, DWORD PTR MyClass::MyFunction
    

    <我不知道GCC ASM块特性是否需要这个。< /P>成员函数的地址是什么?它存储在C++变量中,在需要时从另一个内联汇编块调用。通常,我甚至从来没有想过实现如此丑陋和反常的东西。你必须在汇编中硬编码吗?如果没有其他方法,我必须重写所有这些逻辑,但我真的希望有一个更简单的解决方案……你能计算C++中的偏移量并将它存储在一个本地变量中,你可以从ASM代码中访问吗?嗯,是的,但是那个关键字不存在于GCC中。我想你误解了方向。@Xeo:我没有误解方向,我只是指出这个来自MSVC的汇编程序正在使用它。至于GCC不支持偏移量,它支持,您只需要绑定到一个装饰符号,请参见我的更新示例非常感谢,Necrolis和Xeo!嗯,我尝试了各种各样的方法,但我的错误不是在
    mov
    上,而是在
    call[eax]
    测试上,看看它是否有效+1,至少在MSVC上工作
    mov eax, DWORD PTR MyClass::MyFunction