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

时间:2011-06-03 12:46:03

标签: c++ visual-c++ gcc assembly inline-assembly

尝试使用 -fasm尝试使用Apple GCC 4.2.1 进行编译时,尝试将偏移关键字替换为 __ offsetof -blocks 参数(启用 Intel样式汇编语法)在MSVC中工作的内联汇编代码,我收到错误:无法将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
    };
}


有人可以告诉我,我该怎么办?似乎我正在移植的应用程序的整个结构基于这个该死的偏移宏......

4 个答案:

答案 0 :(得分:2)

offsetof从结构的开头获取成员的偏移量,但在这种意义上,函数是 不是 成员(甚至不是虚函数)。你可能会追求的是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-blocks只有苹果)我们会这样做(32位exe,在windows 7 64bit下测试,使用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;
}

海湾合作委员会的问题是:

  1. 您无法绑定到自动内联函数,因为没有生成符号(因此无法使用)。
  2. 你需要绑定到装饰符号,除非你强制未修饰的符号(即使那时仍然会有一些装饰)

答案 1 :(得分:1)

试试这个:

mov eax, MyClass::MyFunction

它说什么?

PS:在旧的英特尔语法中,这必须类似于

mov eax, DWORD PTR MyClass::MyFunction

我不知道gcc asm-block功能是否需要这个。

答案 2 :(得分:0)

由于您说您不需要对其进行硬编码,只需在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. :)
  }
}

答案 3 :(得分:0)

您不能将offsetof与成员函数一起使用,只能与数据成员一起使用。这没有道理。成员函数实际上并不存储在类中。