关于c#的问题很少

本文关键字:问题 关于 | 更新日期: 2023-09-27 18:02:04

有人能回答这些问题吗?

1( 有一个微软的类: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类获得句柄,以及他是如何做到的?

关于c#的问题很少

  1. 此方法在内部实现为非托管函数。您可以下载共享源公共语言并查看该方法的实现

这里是我在safechandr.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

但我不确定它是否有用。


现在是第二个问题。

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

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

当您调用任何采用DWORDPVOID的非托管代码时,我们可以传递SafeHandle或其子代之一。

例如,如果我们的人工DLL中有几个外部函数:

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

我们可以用以下方式称呼他们:

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

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

正如MethodImplAttribute的参数可能建议的那样,您在第一个问题中询问的方法被烘焙到CLR中——它们就是。NET等效的内核调用。

至于第二个问题,类型封送处理由CLR处理。根据微软的一篇文章,"对于每种.NET Framework类型,都有一个默认的非托管类型,公共语言运行库将使用它在托管到非托管函数调用中封送数据。"在Sergey提供的链接中,有一个定义的类(在"marshalizer.h"中(,名为SafeHandleMarshaller;这似乎是将CCD_ 15转换为本地CCD_。

当然,SSCL并不是真正的CLR代码库;尽管如此,它还是对P/Invoke编组的工作原理有了足够好的了解。