将C#结构传递给C++包装器的C++/CLI
本文关键字:C++ 包装 CLI 结构 | 更新日期: 2023-09-27 18:26:43
昨天发布了一个问题后,我以为我已经解决了这个问题,但我仍然有问题,我有一个C++类的C++/CLI包装器,C++类的一些函数将recv的缓冲区作为参数,数据包结构被定义为C++结构,这就是参数。
在C#中,我使用structlayout复制了这些C++结构,这样我在C#中就有了等效的结构,它们在内存中的布局与我的C++结构相同。在我的C++/CLI代码中,我尝试了以下
UINT GetValues(value class^ JPVals) // value class, as C# structs are value types
{
IntPtr ptr;
Marshal::StructureToPtr(JPVals,ptr,false);
return m_pComms->GetValues(ptr,0); // m_pComms is a wrapped unmanaged class
//GetValues takes a pointer to a C++ struct
}
我得到的错误是无法将参数1从"System::IntPtr"转换为"SJPVal*",为什么不可能将Marshall从值类转换为C++结构指针?在这种情况下,我应该传递什么?我应该如何组织它?
您没有得到序列化过程:
// !! Note the % !!
UINT GetValues(value class% JPVals) // value class, as C# structs are value types
{
// Allocate a buffer for serialization, pointer to NULL otherwise
IntPtr ptr = Marshal::AllocHGlobal(Marshal::SizeOf(JPVals));
try {
// Serialize the managed object to "static" memory (not managed by the GC)
Marshal::StructureToPtr(JPVals, ptr, false);
// Pass it to unmanaged code that will modify it.
auto ret = m_pComms->GetValues(reinterpret_cast<SJPVal*>(ptr.ToPointer()), 0);
// Copies the modifications back
Marshal::PtrToStructure(ptr, JPVals);
// Free resources
Marshal::FreeHGlobal(ptr);
return ret;
} catch (...) {
// Make sure we free the memory
Marshal.FreeHGlobal(ptr);
throw;
}
}
编辑:显示了如何复制回值。
当您使用C#struct
时,您需要通过引用传递它,以确保更改被复制回来。或者,该代码将与C#class
一样工作。现在,第一步(StructureToPtr
)可能没有用,因为在调用GetValues
之前,您可能不关心里面有什么。
顺便说一下,你的命名约定有点糟糕。您应该NOT在C++中以大写字母开头变量名。