有人可以回答这些问题吗?
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>
答案 0 :(得分: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
。
当您调用任何需要DWORD
或PVOID
的非托管代码时,我们可以传递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);
MySafeHandle
是SafeHandle
类的子类,知道如何处理该特定资源。
答案 1 :(得分:0)
正如MethodImplAttribute
的论证可能暗示的那样,你在第一个问题中提出的方法都被用于CLR - 它们是.NET等效的内核调用。
关于你的第二个问题,类型编组是由CLR处理的。根据{{3}},“对于每种.NET Framework类型,都有一个默认的非托管类型,公共语言运行库将使用它来整理托管到非托管函数调用的数据。”在Sergey给出的链接中,有一个名为SafeHandleMarshaller
的(在“marshaler.h”中定义的类;这似乎是SafeWaitHandle
转换为原生HANDLE
的机制。
当然,SSCL不是实际的CLR代码库;尽管如此,它对P / Invoke编组的工作方式提供了足够的了解。