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

发布于 2025-01-09 08:47:18 字数 771 浏览 0 评论 0原文

我有包含原始类型和枚举的对象数组;如何将指向此数据的指针封送到具有签名 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 中的地址已正确传递到本机端,但内存的内容不是我所期望的。我现在做错了什么?

I have array of objects holding primitive types and enums; how do I marshal a pointer to this data to a native function with the signature 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); 

Thanks!

EDIT. My second attempt was to do the following:

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);

Now, the addresses stored in testArray are getting passed correctly to the native side but the contents of the memory is not what I am expecting. What am I doing wrong now?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

臻嫒无言 2025-01-16 08:47:18

枚举不是 blittable,因此编组对象数组需要特殊考虑(即,您不能只是 pin_ptr 数组并将其传递到本机/托管边界)。我决定使用 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[]);

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

Enums are not blittable so marshaling an array of objects require special consideration (i.e. you can't just pin_ptr the array and pass it over the native/managed boundary). I decided to use a VARIANT to hold the primitive & enum values and did so with the following code:

// 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);
            

The native function's signature became

void native_function(VARIANT values[]);

There might be a more efficient way to do this but this is what I was able to come up with. Please let me know if you have a more efficient way to accomplish what am I doing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文