c++ - 使用基于堆的数据调用将堆栈对象作为参数的函数

标签 c++ assembly parameter-passing heap-memory inline-assembly

我有一个复杂的问题需要解决,因为我被困住了,根本找不到解决这个问题的方法。 这是代码

struct MyStruct
{
    int x;    
    float y;
    char c;
};

void foo(MyStruct a_myStruct);

int _tmain(int argc, _TCHAR* argv[])    
{
    void *pMyStruct = malloc(sizeof(MyStruct));
    int* pInt = (int*)pMyStruct;

    *pInt = 10;    
    pInt++;

    float *pFloat = (float*)pInt;    
    *pFloat = 2.545;   
    pFloat++;

    char *pChar = (char*)pFloat;
    *pChar = 'c';

    _asm
    {
        pMyStruct
        call foo
    }

    return 0;
}

void foo(MyStruct a_myStruct)
{
}

在这里您可以看到 foo 正在对堆栈上的对象进行操作,并且期望在调用 foo 时映射堆栈对象。但不幸的是 MyStruct 类型在编译时是未知的,所以我必须创建内存块,然后在运行时将数据填充到该 block 中,然后在 foo 获取时传递如上所示用 asm 调用。

现在如何将堆空指针转换为堆栈类型对象。不知何故,如果我得到 fooa_myStruct 参数的地址,我可以用 void* 指向那个位置,但我还是不能取消引用void* 以便将其转换为 MyStruct 类型的对象。

还有其他解决问题的方法吗?与在 C++ 中一样,我们也可以在运行时确定类型。


我在运行时调用 C++ 中的函数时遇到问题,它可能具有带有编译时未知的完整用户定义类型的签名。但是这些类型的详细信息对我可用(因为我破译了某些类型的详细信息来自类型库或来自 DIA SDK)。但现在主要的问题是我想在运行时调用这些函数。在编译时,我只有函数地址和用户定义类型的详细信息,其中对象或指针作为该函数签名的参数参与。现在,如果我想在运行时调用该函数,我需要首先在运行时通过在堆上创建临时 block 并用数据填充该 block 来填充该类型。我拥有该类型的所有详细信息。

现在的问题是我不知道那个函数将参数作为我有详细信息的那种类型的指针,或者那个参数恰好是那种类型的堆栈对象。如果我有指向该类型的指针,那没问题,但如果有对象,我在运行时调用该函数就会遇到很大问题。

最佳答案

我不明白为什么您认为需要按照显示的方式填充结构,但无论如何,您做错了。

它需要更像:

int* pInt = (int*)pMyStruct;   
*pInt++ = 10;   
 float *pFloat = (float*)pInt;   
 *pFloat++ = 2.545;   
 char *pChar = (char*)pFloat;   
 *pChar = 'c';   

这完全依赖于平台,而且可能也无法正常工作。

假设您填充了 myStruct,一种调用 foo 的简单解决方案将其更改为:to

void foo(MyStruct* pMyStruct);

如果不可能,则需要将其复制到堆栈中。就像是 <罢工>

<罢工>
 char rawBytes[sizeof(MyStruct)];
 memcpy(&rawBytes,MyStruct,sizeof(MyStruct));
 foo(*(MyStruct*)rawBytes)`

<罢工> 可能有效。或者不是,因为您在编译时不知道 MyStruct,编译器无法生成堆栈操作代码。

我假设您在运行时确实知道 MyStruct 有多大。所以它必须更像这样:

 _asm{ 
    //pseudo-assembly
    cx = numBytesInMyStruct
    bx = pointerToYourFakeMyStruct
    loop cx
     push *bx++
    call foo
 }

关于c++ - 使用基于堆的数据调用将堆栈对象作为参数的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3427129/

相关文章:

assembly - ELF 程序头偏移

c - 为什么编译器会生成这段代码?

javascript - Reactjs app div onclick 在 IE 11 中不起作用,没有调用任何函数

oracle - 从函数返回 Oracle 关联数组

asp.net-mvc - 如何使用 ajax get 或 post 在 mvc 中使用参数将数据从 View 传递到 Controller

c++ - C++中字符串的堆栈溢出?

c++ - 提振 spirit ,为什么需要 as<> 指令? (又名帮助我理解属性兼容性规则)

c++ - 在Windows中获得准确的堆使用情况(用于在单个进程中调试内存泄漏)

c++ - 枚举类的值超出范围

linux - 编写 AMD64 SysV 程序集时使用哪些寄存器作为临时寄存器?