我是托管代码的新手,我需要使用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*
谁能看到问题出在哪里?
我是否需要使用非托管阵列然后转换为托管?如果是,我该怎么做?
答案 0 :(得分:2)
在托管数组中传递非托管指针可能是有效的C ++ / CLI,但它绝对不是理想的做事方式。请考虑在C ++ / CLI中创建自定义托管类(ref class
)来保存结构,而不是传递指针。
为此,我假设struct1和struct2是 unmanged 结构。这个答案仅适用于这种情况。
您现有的代码适合我。这是我的版本,添加了一些调试。
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);
}
输出:
ptr[0] = 00000000 ptr[1] = 00000000 ptr[0] = 0013F390 ptr[1] = 0013F394 pointerToStructObj1->foo = 4
要使用Debug :: WriteLine,请添加using namespace System::Diagnostics
。
调试器不知道如何显示void*
的内容,因此它只显示空白。它确实以不同的方式显示空指针,但是:null显示为<undefined value>
,非空显示为空白。
我在C ++ / CLI上的理念是:如果您要编写托管代码,编写托管代码。考虑使用托管列表替换向量。如果您仍然需要非托管对象,我强烈建议您考虑使用正确类型的指针编写托管类,而不是void*
数组。
要实现这样的类,请创建所需的任何字段,只要确保它们是指针,而不是直接指针。 (vector<foo>*
而不是vector<foo>
。)在构造函数中使用new
创建对象,并在析构函数中使用delete
(在Dispose上调用)&amp;终结。