C++ 使用基于堆的数据调用以堆栈对象为参数的函数

C++ 使用基于堆的数据调用以堆栈对象为参数的函数,c++,assembly,heap,parameter-passing,inline-assembly,C++,Assembly,Heap,Parameter Passing,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*)pMy

我有一个复杂的问题要解决,因为我被卡住了,根本没有办法解决这个问题。 这是密码

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
类型,因此我必须创建内存块,然后在运行时在该块中填充数据,然后在asm调用
foo
时传递数据,如上所示

现在如何将堆空指针转换为堆栈类型对象。不知何故,如果我得到
foo
a_myStruct
参数的地址,我可以用
void*
指向该位置,但我不能取消对
void*
的引用,从而将其转换为
myStruct
类型的对象

还有别的办法解决这个问题吗?与C++一样,我们也可以在运行时确定类型。
<>我在C++中有一个问题,在运行时调用函数,它可能有在编译时不知道的用户定义类型的签名。但是这些类型的细节对我来说是可用的(因为我从类型库或DIADSK中解密了某些类型的细节)。但主要的问题是,现在我想在运行时调用这些函数。在编译时,我只有函数的地址和用户定义类型的详细信息,对象或指针作为函数签名的参数参与其中。现在,若我想在运行时调用该函数,我需要首先在运行时通过在堆上创建临时块并用数据填充该块来填充该类型。我有该类型的所有详细信息


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

我不明白为什么您认为需要以显示的方式填充结构,但不管怎样,您做得不对

它需要更像:

int* pInt = (int*)pMyStruct;   
*pInt++ = 10;   
 float *pFloat = (float*)pInt;   
 *pFloat++ = 2.545;   
 char *pChar = (char*)pFloat;   
 *pChar = 'c';   
这完全依赖于平台,可能也无法正常工作

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

void foo(MyStruct* pMyStruct);
如果不可能,则需要将其复制到堆栈中。差不多

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

我假设您在运行时知道MyStruct有多大。所以应该更像这样:

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

我必须承认,即使你提供了更多的信息,我也不完全理解你的问题。但是让我说一些关于堆栈、堆和C++的一般情况:

<强>参数传递给函数是一个特定的C++编译器的实现细节<强>,即,这可以从一个C++编译器到下一个编译器。将参数传递到函数中的方法称为调用约定。有些编译器既不使用堆栈也不使用堆来传递参数;相反,如果可能的话,它们使用CPU寄存器。(WATCOM的C++编译器是一个突出的例子,它支持寄存器将参数传递给函数)。 <>这意味着任何C++编译器都可以创建不属于强>二进制兼容< /强>的二进制文件到另一个C++编译器。(C++语言标准没有规定编译输出的二进制标准,因此不同的编译器可能产生二进制不兼容输出;但是任何C++编译器都至少保证二进制兼容)。因此,如果您想使用一个库,则有三种选项:

    < L> > P>选择与特定C++编译器和链接器匹配的二进制文件;
  • 使用编译器自己编译库源代码;或

  • > p>选择一个遵守二进制标准的库二进制(如DLL库格式或微软COM标准),它也由C++编译器和链接器支持。

总之,关于堆栈对象与堆对象的问题没有意义。C++中没有“堆栈对象”这类东西。您没有明确的控制参数传递给函数的原因,因为C++编译器会自行决定如何做这件事,同时似乎存在关键字和特殊语法来控制这种行为(即引用、指针、以及<代码> Audio< <代码> >和<代码>登记> <代码>关键字),它们通常不会保证以特定方式传递参数。如果您熟悉某个特定的编译器,那么您可能能够推断参数传递是如何与此编译器一起工作的。。。但一般来说,你不能——也不应该——了解这种机制


p.S.:我忘了提到术语“堆栈对象”不仅仅在参数传递方面毫无意义。更一般地说,根本没有任何方法告诉编译器在堆栈上分配对象。虽然局部变量通常会在堆栈上分配,但对此没有任何保证。我想这就是您选择跳转到汇编语言的原因。然后可以显式地
pop
值推送到堆栈或从堆栈中取出(由CPU管理)。

您到底想在这里做什么?不管怎么说,这个代码完全没有意义。也许你应该退后一步,解释你试图解决的真正问题。试图将结构转换为指向其成员变量类型的指针意味着你不知道结构是如何工作的。在这件事上我和詹姆斯是一致的。这个代码毫无意义。
 _asm{ 
    //pseudo-assembly
    cx = numBytesInMyStruct
    bx = pointerToYourFakeMyStruct
    loop cx
     push *bx++
    call foo
 }