C# 哪些“IntPtr”口味适合“SafeHandle”`
我得到了一个CA2006(C# 哪些“IntPtr”口味适合“SafeHandle”`,c#,winapi,pinvoke,roslyn-code-analysis,safehandle,C#,Winapi,Pinvoke,Roslyn Code Analysis,Safehandle,我得到了一个CA2006(查看…(一个“IntPtr”实例)的用法,以确定是否应该用SafeHandle或CriticalHandle替换它对于从convertStringSecurityDescriptorSecurityDescriptor返回的IntPtr,我知道它是一个可以用freellocal释放的安全描述符。我只是简单地使用它,可能没有泄漏内存。据我所知,没有相关的内核句柄 有许多SafeHandle子类,它们似乎都没有在包装对象的生命周期结束时调用freellocal。但是,我找不
查看…(一个“IntPtr”实例)的用法,以确定是否应该用SafeHandle或CriticalHandle替换它对于从convertStringSecurityDescriptorSecurityDescriptor
返回的IntPtr
,我知道它是一个可以用freellocal
释放的安全描述符。我只是简单地使用它,可能没有泄漏内存。据我所知,没有相关的内核句柄
有许多SafeHandle
子类,它们似乎都没有在包装对象的生命周期结束时调用freellocal
。但是,我找不到任何关于哪些IntPtr
实例(例如,由Win32 API返回的实例)由SafeHandle
有效管理以及哪些实例不是有效管理的明确信息
我是否应该取消CA警告
更重要的是,如何为我将遇到的下一次IntPtr
使用确定相同的值
(一个能够将SafeHandle
子类映射到最终释放句柄的函数的表将是非常好的。)如果您的问题是“是否已经有一个SafeHandle
子类调用LocalFree
来释放其句柄”,那么是的,有——它是。该类是内部的
,因此一般公众无法使用它,但是如果您想重新创建它,代码是显而易见的。如果你的问题是“我应该使用这样一门课吗”,那么,这有点像是判断。文档还解释了设计原理:SafeHandle
避免了多线程场景中的句柄回收问题,并对P/Invokes提供了特殊支持,以确保在使用非托管代码之前不会意外释放句柄
什么时候IntPtr
是可以被SafeHandle
包装的句柄?您无法从IntPtr
中辨别,您必须知道返回IntPtr
的函数是什么。它将记录您是否正在处理句柄,如果是,则在处理完句柄后应如何关闭句柄(通常,但决不总是,CloseHandle
)。如果您只有一个P/Invoke签名,那么从技术上讲,您什么都没有。特别是,如果它是句柄,则无法确定应该调用什么函数来释放句柄。IntPtr
还可用于封送PVOID
或SIZE\T
或P
(即使out
或ref
参数更自然)或任何其他假定为指针大小的类型
任何超出单个函数(尤其是存储在字段中的函数)的句柄-IntPtr
都是SafeHandle
包装器的理想选择,同时使用多个IntPtr
也是如此(以防止意外地混淆不兼容的句柄)。对于不涉及多线程且不让句柄超出其范围的简单一次性操作,请尝试使用try。。最后
block可能就足够了。如果您愿意,为了一致性(或明确记录您正在处理的对象类型),可以将所有内容都包装在SafeHandle
中,但这并不一定会带来更好的结果。句柄回收是一个严重的问题,但在这里不是一个问题,因为句柄是本地内存的,可靠性不是问题,因为任何严重到足以绕过最后
块的问题也严重到足以使小内存泄漏成为非问题
您的特定场景(将SDDL解析成安全描述符)已经以框架的形式实现,您应该考虑使用该框架来帮助重新创建车轮。(和/或实现您自己的
SecurityDescriptor
子类,如果中的现有类尚未涵盖该子类。RawSecurityDescriptor
也P/调用convertstringsecuritydescriptortosecuritydescriptorrw
,而不需要使用SafeHandle
。框架代码应该不需要必须被视为做什么的好例子(大量代码违反了官方指南)这是一件事。这不是错误的,只是严重的过度杀戮。当你编写一个终结器来释放资源时,你会考虑它。@汉斯本-这是有帮助的,但是终结器本身就是灰色区域野兽。它们是把资源的生命周期连接到另一个随机资源(小的托管堆块)。.他们充其量只是第二级防御,靠自己的力量永远无法可靠地完成任何事情。