2011-07-15 29 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