如何使用 C++/CLI 有效地将对象数组编组为本机函数

How to efficiently marshal array of objects to native function using C++/CLI

我有一组包含基本类型和枚举的对象;如何将指向此数据的指针编组为具有签名 native_func(void* ptr[]).

的本机函数
array<System::Object^>^ values = gcnew array<System::Object>(64);

// ... populate the managed array with primitives ...

// data is pinned and won't be moved by the GC
pin_ptr<object> pinned = &values[0]; 

// not sure what do here... data is corrupted in the native code
native_func((void**)pinned); 

谢谢!

编辑。我的第二次尝试是执行以下操作:

pin_ptr<object> pinned = &values[0]; 
void* testArray[64];
for (auto i = 0; i < values->Length; i++)
{
    testArray[i] = (void*)Marshal::UnsafeAddrOfPinnedArrayElement(values, i);
}
native_func(testArray);

现在,存储在 testArray 中的地址已正确传递到本机端,但内存中的内容不是我所期望的。我现在做错了什么?

枚举不可 blittable,因此编组对象数组需要特别考虑(即您不能只 pin_ptr 数组并将其传递到 native/managed 边界)。我决定使用 VARIANT 来保存原始值和枚举值,并使用以下代码实现:

// allocate a managed array of size 64 (it's enough for my application)
array<System::Object^>^ values = gcnew array<System::Object>(64);

// stack allocate a native array of size 64 
VARIANT nativeValueArray[64] = {}; 

// ... populate the managed array ...

for (auto i = 0; i < values->Length; i++)
{
    Marshal::GetNativeVariantForObject(values[i], (IntPtr)(void*)&nativeValueArray[i]);
}

// pass the array of native VARIANTS to the native function "native_function"
native_function(nativeValueArray);
            

本机函数的签名变为

void native_function(VARIANT values[]);

可能有更有效的方法来执行此操作,但这是我能够想出的方法。如果您有更有效的方法来完成我正在做的事情,请告诉我。