首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MSDN SafeHandle示例

MSDN SafeHandle示例
EN

Stack Overflow用户
提问于 2018-09-04 18:13:17
回答 1查看 695关注 0票数 8

也许是个愚蠢的问题..。我是C#和.Net的新手。

在MSDN上的SafeHandle类(C#)的示例中,代码让我有点抓狂。

代码语言:javascript
复制
[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函数CreateFile的Win32句柄是如何进入MySafeFileHandle对象受保护的IntPtr“句柄”变量的?MySafeFileHandle的构造函数是私有的,甚至不以IntPtr作为参数!

CreateFile声明上的评论说明了一些关于

…CLR的平台编组层将以原子方式将句柄存储到SafeHandle对象中。

我不知道这意味着什么,谁能解释一下吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-05 12:09:31

简短的回答:这是魔法。运行时知道如何正确地将非托管句柄(只是指针大小的值)转换为SafeHandle和back。

很长的答案:这是足够先进的技术。具体来说,ILSafeHandleMarshaler是(非托管的!)类,它负责前后封送SafeHandle的封送。源代码对此过程进行了有益的总结:

// 1)为新的安全句柄// 2创建本地文件// 2)预分配一个安全句柄// 3)创建本地以保存返回的句柄// 4)将byref IntPtr添加到本机sig / 5)

它发出的将非托管句柄加载到安全句柄中的代码实际上是托管代码,尽管托管代码很高兴地忽略了可访问性。它获取并调用默认构造函数以创建新实例:

代码语言:javascript
复制
MethodDesc* pMDCtor = pMT->GetDefaultConstructor();
pslIL->EmitNEWOBJ(pslIL->GetToken(pMDCtor), 0);
pslIL->EmitSTLOC(dwReturnHandleLocal);   

然后直接设置SafeHandle.handle字段:

代码语言:javascript
复制
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字段实际上都是不可访问的,但是这段代码不受可见性检查的限制。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52171900

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档