如何使用 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[]);
可能有更有效的方法来执行此操作,但这是我能够想出的方法。如果您有更有效的方法来完成我正在做的事情,请告诉我。
我有一组包含基本类型和枚举的对象;如何将指向此数据的指针编组为具有签名 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[]);
可能有更有效的方法来执行此操作,但这是我能够想出的方法。如果您有更有效的方法来完成我正在做的事情,请告诉我。