.net - P/Invoke 和非托管 DLL 状态

标签 .net c pinvoke

我有一个程序集和一个非托管 DLL。我尝试在非托管 DLL 中使用静态变量,但它似乎无法在来自程序集的调用之间存在。

我想知道非托管 DLL 中的静态变量是否可以在 P/Invoke 调用之间存在,可能是我在代码中漏掉了一些东西。如果不是,如果全局静态变量不是一个选项,那么为此类非托管 DLL 存储状态的最佳方法是什么?

最佳答案

.Net 运行时通常不会自行卸载您的 pinvoke DLL,因为它无法知道这样做是否安全,例如它们是否包含状态,包括静态字符串或其他全局变量。

在你的问题中不清楚你是指 .Net 端的 static 还是非托管端的 static/const。如果您的意思是托管端的一个,那么它不能保证在调用返回后存在,如果它被编码,并且取决于托管端的调用设置,除非您遵循一些非常具体的规则。如果它只是一个计划编号,那么它并不重要,所以我将假设它是一个字符串或其他更复杂的结构。

例如,如果被调用方是 dll 中需要 ansi 字符串的 c 函数,并且您让 pinvoke 获取 C# 字符串,它将为您将 c# unicode 字符串编码为 asni 字符串,并期望得到在调用完成后回收该内存,即使该字符串来自 C# 静态。即使情况并非如此,调用后任何指向托管内存的指针都应被视为无效,除非您固定该内存。

Here is some rope to hang yourself :)小心使用它。这将无限期地锚定托管内存,我不建议这样做。拥有自己的字符串副本的 DLL,或拥有自己的副本的托管端,不会是有史以来最大的编程犯罪。实际上,如果他们每个人都有一个在他们自己的堆中,如果它确实是静态的,那么实际上会快得多。 C 函数需要在调用返回之前创建自己的副本。

关于.net - P/Invoke 和非托管 DLL 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6029929/

相关文章:

c# - 我应该如何使用 P/Invoke 将字符串数组传递给 C 库?

c# - 将自定义 EventArgs 作为事件参数传递

java - 如何使用JAVA读取C/Matlab创建的二进制文件

c - 使用指针传递 2D 数组 (C)

c - Kerberos 获得初始凭证

c# - 如何使用 Hardware ID Extractor 修复 Ntdll.dll APPCRASH?

c# - 来自 user32.dll 的 FindWindowEx 使用 dllimport 返回零句柄和 127 错误代码

.net - 在启动之前检查 .NET 依赖项

c# - 使用 ScriptService 时为 "Google.GoogleApiException: Google.Apis.Requests.RequestError Request is missing required authentication credential"

c# - 如何读取 Stream 并将其位置重置为零,即使 stream.CanSeek == false