gpt4 book ai didi

c# - 指向 native C++ 堆的指针上的 Marshal.PtrToStructure 是否正常?

转载 作者:行者123 更新时间:2023-12-01 14:19:59 40 4
gpt4 key购买 nike

我有一个使用 PInvoke 在 C# 和 C++ 之间编码数据的应用程序。该应用程序是一个本地 C++ 应用程序,它在内部使用 C# 部分启动 CLR。​​

有时我必须将数据从 C++ 编码到 C#,我正在使用 Marshal.PtrToStructure为了这。 C++ 部分基本上是这样的:

struct X {};

auto xPtr = new X; // somewhere in the application

callCSharp(xPtr); // somewhere else

C# 部分是这样的:

public void callCSharp(IntPtr xPtr)
{
var x = Marshal.PtrToStructure<X>(xPtr);
}

此代码适用于我的 Windows 10 计算机,但我不确定使用此代码是否会遇到问题。生命周期管理全部在 C++ 中完成,因此我不必在 C# 端分配或释放任何东西。但是我不确定 CLR 是否总是可以访问 native 堆。 xPtr使用 new 分配因此位于 C++ 应用程序的 native 堆上。 Marshal.PtrToStructure<X>(xPtr)然后尝试读取该位置的内存,但我不知道这是否会导致问题。

我读过 this这表明 C++ 应用程序和 CLR 使用相同的堆(即 GetProcessHeap),因此这似乎支持我对 Windows 10 的发现,但对于其他操作系统版本可能有所不同。

我的示例代码是否健全?这里有什么陷阱吗?此代码是否适用于 Windows 7、8 和 10?

最佳答案

是的,只要 C/C++ 代码不释放内存,这是完全合理和安全的。请注意,并不总是需要(或希望)使用 Marshal这里;取决于什么 <X>是的,您也可以以其他方式做到这一点,包括:

  • unsafe (将 void* 转换为 X* )
  • Unsafe.AsRef<X>(...) (将 void* 转换为 ref X )
  • new Span<X>(...) (它从 X 创建了一定数量的 void* 的跨度;跨度就像一个 vector ,但与任意内存对话)

所有这些都是零拷贝方法,这意味着您的 C# 代码然后直接与完全相同的内存空间对话,而不是本地快照;但是如果您取消引用指针(托管或非托管)到一个非引用本地,那么它将制作一个拷贝。

关于c# - 指向 native C++ 堆的指针上的 Marshal.PtrToStructure 是否正常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63561834/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com