2013-12-12 48 views
1

我有用C++编写的方法返回一个对象。这个方法是通过程序集调用的(一个非常长时间的原因)。例如:从程序集中调用C++方法返回对象数据

Person DoStuff(int a) 
{ 
    Person output; 

    output.Name = "Koder"; 
    output.Age = 1337; 
    output.Cash = 80.86; 

    cout << "Given number is " << a << endl; 

    return output; 
} 

我知道价值回报是讨厌和坏,但这个问题不是这个问题。调用此方法如下所示:

Variant vMethod = &DoStuff; 
void* pMethod = vMethod.As<void*>(); 

int paramVal = 78; 

int* retVal = nullptr; 

__asm 
{ 
    push paramVal 
    call pMethod 
    mov retVal, EAX 
} 

当此方法的返回值为int时,此功能完美无缺。但是现在返回一个对象,实际的call指令引发了一个异常。您可以猜到,例外是return声明。我知道这会发生,当我这样写,但我不知道如何检索非原始(或非整数,就此而言)返回值。谷歌搜索C++ /汇编函数调用没有帮助很多。感谢任何能提供帮助的人。

+2

我对此没有线索......我最好的猜测是:使用C++调用函数,然后不生成可执行文件,尝试生成汇编代码(gcc -S)并查看返回值被处理。 –

+0

帮助解散代码。我能够看到如何初始化要调用的方法的堆栈并返回要检索的值。谢谢! –

回答

1

这取决于使用什么样的呼叫Calling Convention。它也取决于编译器如何处理对象。在这种情况下,您的对象至少包含3个值,这使得所有值都不可能适合寄存器(您的代码假设返回值将位于EAX中 - 如果您返回的是int,则返回值)。

从查看程序集看起来您使用的是x86 32位程序集。 在这种情况下,调用约定说你应该在堆栈上传递参数, 对于这种情况,我认为x86位调用约定说你需要为返回值自己保留内存并传递对象应该存储的地址作为参数。在Windows上,返回指针(用于存储对象的地址)是第二个参数,在Linux上是第一个参数。

由于您未能做到这一点,DoStuff方法可能会覆盖返回地址,并导致程序在返回指令上崩溃。

+0

这个,以及提供的评论,让我弄清楚了。我需要为输出保留堆栈空间,并且将WORD中的对象反向(从右到左)推入堆栈。 –

相关问题