【问题标题】:Passing C# struct to C++/CLI for C++ wrapper将 C# 结构传递给 C++/CLI 用于 C++ 包装器
【发布时间】:2012-03-06 07:51:38
【问题描述】:

昨天发布一个问题后,我以为我已经解决了这个问题,但我仍然遇到问题,我有一个 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++ 结构指针?在这种情况下,我应该传递什么以及我应该如何编组它?

【问题讨论】:

  • 那么你应该接受昨天问题的答案。

标签: c# c++ interop c++-cli


【解决方案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++ 中以大写字母开头变量名。

【讨论】:

  • 愚蠢的错误:我的意思是不要以大写字母开头的变量名,对不起,我已经编辑了答案。
  • 其实我还有一个问题,传入的结构是调用winsock recv()的缓冲区,在调用函数中,用户需要能够传入结构,然后在函数调用 struct 会被数据填充,因为 IntPtr 在函数中分配了内存现在仍然会发生这种情况,IntPtr 可以指向与传入的 struct 相同的内存吗?
  • 不,它不能,但是你可以使用逆函数Marshal::PtrToStructure将它复制回来。我会编辑并告诉你怎么做。
  • 请注意参数列表中的%
  • “第一步(StructureToPtr)现在可能没用了”......那么如果我不再执行 StructureToPtr,我该如何将它传递给 C++ 函数?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-18
相关资源
最近更新 更多