昨天发布问题之后我认为我已经解决了这个问题,但我仍然遇到问题,我有一个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 ++结构指针?在这种情况下,我应该传递什么,我应该如何编组呢?
答案 0 :(得分:1)
您没有获得序列化过程:
// !! 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
之前,您可能并不关心那里的内容。
顺便说一句,你的命名约定有点糟糕。你应该不用C ++中的大写字母开始变量名。