P/Invoke 是不是执行 DLL 然后将其关闭?

Posted

技术标签:

【中文标题】P/Invoke 是不是执行 DLL 然后将其关闭?【英文标题】:Does P/Invoke execute the DLL and then shut it down?P/Invoke 是否执行 DLL 然后将其关闭? 【发布时间】:2013-03-24 12:47:41 【问题描述】:

如果我使用 C# 来 P/Invoke 某个 DLL,实际的 C++ DLL 会在调用期间运行然后被关闭,从而破坏所有使用的内存吗?还是 .NET 会负责 C++ DLL 在非托管“堆”中使用的内存,并在我每次调用静态函数时将指向这些对象的指针指向 C++ DLL?

当我需要某个 C++ 项目使其内存持久化时,我是否应该创建一个 ActiveX/COM 服务器以使其内存持久化,同时又能够从 C# 调用它?

【问题讨论】:

【参考方案1】:

如果我使用 C# 来 P/Invoke 某个 DLL,实际的 C++ DLL 会在调用期间运行然后被关闭,从而破坏所有使用的内存吗?

没有。加载 DLL 后,它将保持加载状态。 DLL 的生命周期与函数调用绑定。这意味着 DLL 中具有静态存储的变量在初始 p/invoke 调用之后仍然存在。

【讨论】:

内存存储在哪里?你能详细说明一下吗? 非托管 DLL 被加载到托管程序的应用程序域的地址空间中。请注意,您可以动态加载和卸载应用程序域,这会在卸载应用程序域时从内存中删除非托管 DLL。 内存存储在哪里?准确回答问题。 我的意思是当由 .NET 应用程序运行时,C++ DLL 的内存存储在哪里? ...“.NET 是否会负责 C++ DLL 在非托管“堆”中使用的内存,并在我每次调用静态函数时将指向这些对象的指针指向 C++ DLL?” 由系统处理。您所拥有的是一个本机的、非托管的 DLL。它加载了对LoadLibrary 的调用。就像 .net 运行时本身一样。 .net 不“负责”任何事情。它只是使用标准平台机制来加载 DLL。【参考方案2】:

如果您从 C++-DLL 创建一个对象,它实际上会一直存在,直到您删除它或更确切地说是释放它。由于您需要手动删除非托管对象,因此它将保留。

【讨论】:

因此,是否有可能让一个功能齐全的 C++ 项目作为 DLL 运行,并从 .NET 获得简单的静态函数 P/Invoke,而 C++ 端没有任何中断?即使 C++ 项目使用对象和 DirectX 和复杂的东西? 这取决于你对全功能的理解?例如COM,您正在创建非托管组件,然后您可以在托管环境中使用这些组件。所以应该是可能的。

以上是关于P/Invoke 是不是执行 DLL 然后将其关闭?的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中为 p/invoke 创建一个基本的 C++ .dll

使用 P/Invoke 调用 dll 时,为啥 LoadLibrary 在某些机器上会失败?

P/Invoke 动态 DLL 搜索路径

如何从 Metro P/Invoke 到本机 dll?

C++/C# 互操作中的内存映射和 P/Invoke 性能

P/Invoke之C#调用动态链接库DLL