微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 C++ DLL 的 C# 应用程序的内存使用情况

如何解决使用 C++ DLL 的 C# 应用程序的内存使用情况

为了正确起见,如果我对数据流在 C# 程序调用 C++ dll 并将委托作为参数的想象是正确的,我想征求您的意见。

  1. 系统为 C# 程序提供内存
  2. C# 程序加载 .dll 并将其部分空间提供给 C++ dll。在这个空间里不会有 C# 垃圾回收,只有卸载 .dll 才能释放整个空间。
  3. 调用一个 C++ 函数。特定的函数一个委托作为参数。我们深入 C++ 内存区域并声明一些变量。 C++ 函数将在其代码中的某处调用 C# 委托。
  4. C# 委托对 C# 内存进行操作,如果输入参数是本机类型,则在 C# 内存中会有一份其输入参数的副本,或者对 C++ 内存中变量的引用(如果是复杂类型)。如果我们有本机类型,我可以将它保存到 C# 世界中,一切都会好起来的。但是如果它是一个引用并且我只是将它保存到我的 C# 内存中,我会得到未定义的行为,如果我结束我的 C++ 函数,因为变量将超出范围并被销毁。
  5. C# 函数结束,我们得到 C++ 中的返回值作为副本(或指向返回值的指针,如果是复杂类型,则该指针将指向 C# 内存)
  6. C++ 函数结束,C++ 函数使用的内存被释放

我这样做对吗?

解决方法

这应该在 marshaller

的文档中描述

如果它们是本机类型或对 C++ 内存中变量的引用,如果它是复杂类型。如果我们有本机类型,我可以将它保存到 C# 世界中,一切都会好起来的。但是如果它是一个引用并且我只是将它保存到我的 C# 内存中,我会得到未定义的行为,如果我结束我的 C++ 函数,因为变量将超出范围并被销毁

我的理解是编组器将复杂类型转换为结构或指针 (IntPtr)。结构是按值传递的,因此您将在托管内存中(可能在堆栈上)有一个副本。指针需要不安全的代码才能访问,因此您有责任安全地处理它们。

C++ as copy(或者指向返回值的指针,如果是复杂类型,指针会指向C#内存)

托管函数实际上没有办法以安全的方式返回指向托管内存的指针。要创建指针,您需要修复对象以防止 GC 移动它,但修复是有范围的,因此它不适用于返回值。

我个人认为编组规则有点复杂,我更愿意保持任何 p/Invoke 简单,如果没有其他原因,只是为了避免有关安全的问题。对于 c# 和 c++ 之间更复杂的互操作性,我建议使用 c++/cli。这允许您自己进行类型转换,并添加了大量工具,您可以使用它来确保正确运行。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。