关于c#的几个问题

时间:2011-07-15 07:34:44

标签: c#

有人可以回答这些问题吗?

1)有一个Microsoft的类:SafeHandle.cs我查看了源代码,并且有这样的方法:

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern void DangerousAddRef(ref bool success);

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern void DangerousRelease();

这些方法的定义在哪里?我在哪里可以找到它们?

2)有一个方法定义,它从系统库中执行一个方法。

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), SuppressUnmanagedCodeSecurity, DllImport("kernel32.dll", EntryPoint="WaitForSingleObject", SetLastError=true, ExactSpelling=true)]
private static extern int WaitForSingleObjectDontCallThis(SafeWaitHandle handle, int timeout);

通常方法:WaitForSingleObject接受(HANDLE和DWORD)。 .net如何知道如何从SafeWaitHandle类获取句柄以及如何处理它?<​​/ p>

2 个答案:

答案 0 :(得分:2)

  1. 此方法在内部实现为非托管功能。您可以下载Shared Source Common Language并查看该方法实现。
  2. 这里是我在safechandle.cpp文件中找到的代码:

    FCIMPL2(void, SafeHandle::DangerousAddRef, SafeHandle* refThisUNSAFE, CLR_BOOL *pfSuccess)
    {
        CONTRACTL
        {
            THROWS;
            MODE_COOPERATIVE;
            DISABLED(GC_TRIGGERS);
            SO_TOLERANT;
        }
        CONTRACTL_END;
    
        SAFEHANDLEREF sh(refThisUNSAFE);
    
        HELPER_METHOD_FRAME_BEGIN_1(sh);
    
        if (pfSuccess == NULL)
            COMPlusThrow(kNullReferenceException);
    
        sh->AddRef();
        *pfSuccess = TRUE;
    
        HELPER_METHOD_FRAME_END();
    }
    FCIMPLEND
    

    但我不确定它是否有用。


    现在关于第二个问题。

    在从托管代码到本机代码对象的编组过程中,marshallel通过调用SafeHandle方法将任何IntPtr转换为DangerousGetHandle

    在从本机代码解析到托管代码的过程中,存在相反的转换:任何IntPtr都会返回SafeHandle

    当您调用任何需要DWORDPVOID的非托管代码时,我们可以传递SafeHandle或其中一个后代。

    例如,如果我们的umanaged DLL中有一些外部函数:

    PVOID CreateCustomHandle();
    void ReleaseCustomHandle(PVOID handle);
    

    我们可以通过以下方式打电话给他们:

    [DllImport("kernel32")]
    public static extern MySafeHandle CreateCustomHandle();
    
    [DLLImport("kernel32")]
    public static extern void ReleaseCustomHandle(MySafeHandle handle);
    

    MySafeHandleSafeHandle类的子类,知道如何处理该特定资源。

答案 1 :(得分:0)

正如MethodImplAttribute的论证可能暗示的那样,你在第一个问题中提出的方法都被用于CLR - 它们是.NET等效的内核调用。

关于你的第二个问题,类型编组是由CLR处理的。根据{{​​3}},“对于每种.NET Framework类型,都有一个默认的非托管类型,公共语言运行库将使用它来整理托管到非托管函数调用的数据。”在Sergey给出的链接中,有一个名为SafeHandleMarshaller的(在“marshaler.h”中定义的类;这似乎是SafeWaitHandle转换为原生HANDLE的机制。

当然,SSCL不是实际的CLR代码库;尽管如此,它对P / Invoke编组的工作方式提供了足够的了解。