0

我是托管代码的新手,我需要使用 C++/CLI 将指向不同结构的指针数组传递给 Windows 窗体,但它不起作用!

我的问题出在托管数组中,我怎样才能正确访问它的元素。

代码序列:

array<void*> ^ ptr;//here ptr value is undefined , type array<void*> ^
ptr = gcnew array<void*> (2);// length 0x2 , 0x0 and 0x1 values are undefined of type void

class1::struct1 structObj1;
class2::struct2 structObj2;

ptr[0] = &structObj1;// value is empty of type void!!
ptr[1] = &structObj2;//value is empty of type void!!

当我看 ptr 时,我发现了上面的评论。

请注意,重复代码但使用非托管数组可能有效

void* ptr[2];//here ptr value is undefined , type void*[]

class1::struct1 structObj1;
class2::struct2 structObj2;

ptr[0] = &structObj1;// value is address1 of type void*
ptr[1] = &structObj2;//value is address2 of type void*

谁能看出问题出在哪里??

我是否需要使用非托管数组然后转换为托管?如果是,我该怎么做?

4

1 回答 1

2

在托管数组中传递非托管指针可能是有效的 C++/CLI,但它绝对不是做事的理想方式。请考虑创建一个自定义托管类(ref class在 C++/CLI 中)来保存结构,而不是传递指针。

为此,我假设 struct1 和 struct2 是未管理的结构。此答案仅适用于这种情况。

您现有的代码对我有用。这是我的版本,添加了一些调试。

public struct struct1 { int foo; };
public struct struct2 { float bar; };

int main(array<System::String ^> ^args)
{
    array<void*> ^ ptr;
    ptr = gcnew array<void*> (2);

    for(int i = 0; i < ptr->Length; i++)
        Debug::WriteLine("ptr[{0}] = {1:X8}", i, reinterpret_cast<int>(ptr[i]));

    struct1 structObj1;
    struct2 structObj2;

    ptr[0] = &structObj1;
    ptr[1] = &structObj2;

    for(int i = 0; i < ptr->Length; i++)
        Debug::WriteLine("ptr[{0}] = {1:X8}", i, reinterpret_cast<int>(ptr[i]));

    struct1* pointerToStructObj1 = reinterpret_cast<struct1*>(ptr[0]);

    structObj1.foo = 4;
    Debug::WriteLine("pointerToStructObj1->foo = {0}", pointerToStructObj1->foo);
}

输出:

指针 [0] = 00000000
指针 [1] = 00000000
指针[0] = 0013F390
指针[1] = 0013F394
pointerToStructObj1->foo = 4

编辑

要使用 Debug::WriteLine,请添加using namespace System::Diagnostics.

调试器不知道如何显示 a 的内容void*,所以它只显示空白。但是,它确实以不同的方式显示空指针:null 显示为<undefined value>,非 null 显示为空白。

我对 C++/CLI 的理念是:如果您要编写托管代码,请编写托管代码。考虑用托管列表替换您的向量。如果您仍然需要非托管对象,我强烈建议您考虑使用正确类型的指针而不是void*数组编写托管类。

要实现这样一个类,请创建您需要的任何字段,只需确保它们是指针,而不是直接的。(vector<foo>*而不是。)在构造函数中vector<foo>创建对象,并在析构函数(在 Dispose 上调用)和终结器中创建它们。newdelete

于 2013-05-15T15:48:26.917 回答