c# - MSDN SafeHandle 示例
问题描述
也许是一个愚蠢的问题......我是 C# 和 .Net 的新手。
在 MSDN 上的 SafeHandle 类 (C#) 示例中,代码让我有点摸不着头脑。
[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
internal class MySafeFileHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private MySafeFileHandle()
: base(true)
{}
// other code here
}
[SuppressUnmanagedCodeSecurity()]
internal static class NativeMethods
{
// other code...
// Allocate a file object in the kernel, then return a handle to it.
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
internal extern static MySafeFileHandle CreateFile(String fileName,
int dwDesiredAccess, System.IO.FileShare dwShareMode,
IntPtr securityAttrs_MustBeZero, System.IO.FileMode
dwCreationDisposition, int dwFlagsAndAttributes,
IntPtr hTemplateFile_MustBeZero);
// other code...
}
// Later in the code the handle is created like this:
MySafeFileHandle tmpHandle;
tmpHandle = NativeMethods.CreateFile(fileName, NativeMethods.GENERIC_READ,
FileShare.Read, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
我的问题是: C 函数中的 Win32 HANDLE 如何CreateFile
进入MySafeFileHandle
受保护的对象IntPtr
“句柄”变量?的构造函数MySafeFileHandle
是私有的,甚至不接受 aIntPtr
作为参数!
声明上方的评论CreateFile
说了一些关于
... CLR 的平台编组层将以原子方式将句柄存储到 SafeHandle 对象中。
我不确定我确切地知道这意味着什么,有人可以解释一下吗?
解决方案
简短的回答:这很神奇。运行时知道如何正确地SafeHandle
来回转换非托管句柄(只是指针大小的值)。
长答案:这是足够先进的技术。具体来说,ILSafeHandleMarshaler
是(非托管!)类SafeHandle
来回处理编组。源代码有用地总结了这个过程:
// 1) create local for new safehandle // 2) prealloc a safehandle // 3) create local to hold returned handle // 4) [byref] add byref IntPtr to native sig // 5) [byref] pass address of local as last arg // 6) store return value in safehandle
它发出的将非托管句柄加载到安全句柄中的代码实际上是托管代码,尽管托管代码很乐意忽略可访问性。它获取并调用默认构造函数来创建一个新实例:
MethodDesc* pMDCtor = pMT->GetDefaultConstructor();
pslIL->EmitNEWOBJ(pslIL->GetToken(pMDCtor), 0);
pslIL->EmitSTLOC(dwReturnHandleLocal);
然后它直接设置SafeHandle.handle
字段:
mdToken tkNativeHandleField =
pslPostIL->GetToken(MscorlibBinder::GetField(FIELD__SAFE_HANDLE__HANDLE));
...
// 6) store return value in safehandle
pslCleanupIL->EmitLDLOC(dwReturnHandleLocal);
pslCleanupIL->EmitLDLOC(dwReturnNativeHandleLocal);
pslCleanupIL->EmitSTFLD(tkNativeHandleField);
构造函数和handle
字段实际上都不可访问,但此代码不受可见性检查的影响。
推荐阅读
- android - 如何在 Android Developers Doc 中找到 thd 实现细节?
- macos - mac的cpp编译器路径是什么?
- python - 使用 docker-compose 在 Digital Ocean 中的 Dokku 中推送应用程序
- c# - MS Graph SDK 'List schemaExtensions' 过滤语法无法正常工作
- react-native - 一个 socket-io 和一个 WebSocket 连接同时共享断开事件
- excel - VBA Excel 接口实现和继承问题
- windows - Chrome 策略“ExternalProtocolDialogShowAlwaysOpenCheckbox”不起作用
- python - 打开和读取名称转换为用户名并存储在另一个文件中的文件
- java - MappedByteBuffer 与其支持的 RandomAccessFile 之间的关系
- sql - 编写包含除法、总计和百分比的 SQL 查询