2011-07-15 34 views
1

任何人都可以回答这些问题吗?关于c的一些问题#

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类获取句柄以及他如何做到这一点?

+0

@paolo我试图将第一个代码片段格式化为预格式化的块,但无法做任何事情。 – John

+0

[nativeGetUninitializedObject实际存在于哪里?](http://stackoverflow.com/questions/4866179/where-does-nativegetuninitializedobject-actually-exist) –

+0

@John:我不知道。我花了一些时间尝试做同样的事情g自己没有成功...... :) –

回答

2
  1. 该方法在内部实现为非托管函数。您可以下载Shared Source Common Language并查看该方法的实现。

在这里,我在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通过调用DangerousGetHandle方法将任何SafeHandle转换为IntPtr

在从本机代码解编到托管代码的过程中,存在相反的转换:任何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类,知道的子类如何处理该特定资源。

+0

谢谢你帮助我。第二个问题呢? – John

+0

在安全处理到IntPtr转换期间,他如何知道应该调用哪个方法来实际获取底层句柄? (为什么是:DangerousGetHandle) 他如何知道使用哪种方法从IntPtr创建SafeHandle? 或者它可能是通过反射发生的。它正在寻找一个合适的方法来返回预期的变量类型? – John

+0

此编组实际上不会调用DangerousGetHandle,至少我无法找到该方法的直接调用。你可以自己看一下marshaler.h(以及其他文件,比如cgenx86.cpp),但是有很多低级的东西很难阅读和理解。 但是,无论如何,我们可以通过以下方式来解决这个问题:SafeHande可以通过一些内部的CLR内容隐式转换到IntPtr或从IntPtr转换。因此,无论何时,只要在本地代码中使用IntPtr,就应该使用SafeHandle或其中一个后代。 –

0

作为MethodImplAttribute的参数可能表明,您在第一个问题中询问的方法会被引入到CLR中 - 它们是.NET内核调用的等价物。

至于你的第二个问题,类型封送处理由CLR处理。根据article from Microsoft,“对于每个.NET Framework类型,都有一个默认的非托管类型,公共语言运行库将用于将数据封送到托管到非托管函数调用。“以由塞吉给出的链接,有限定的类(在‘marshaler.h’)称为​​;这似乎是由其中SafeWaitHandle转换为原生HANDLE机制

当然,SSCL ISN。不是实际的CLR代码库,但它提供了一个足够好的想法,说明P/Invoke编组如何工作。

+0

谢谢你的回答。 – John