2011-10-11 28 views
1

有誰知道類似於SafeHandle的實現不使用IntPtr,我可以從中派生嗎?或者我應該完全創建一個新的句柄?我需要像DangerousGetHandle()和SetHandle()這樣的函數,因爲這些函數在我使用的庫中都有使用。不使用IntPtr的SafeHandle

我問的原因是我正在編寫一個應用程序,它使用TAPI 2.x的Atapi託管.NET庫(可在此處獲得:http://atapi.codeplex.com/)。應用程序面向32位和64位平臺,目前工作正常,在32位,但在64位上運行時,這條線在圖書館的TapiCall類拋出一個錯誤:

rc = NativeMethods.lineGetCallStatus(_hCall, pLcs); 

第一異常詳細信息的行:

System.ObjectDisposedException was unhandled 
Message=Safe handle has been closed 
Source=mscorlib 
ObjectName="" 
StackTrace: 
at System.StubHelpers.StubHelpers.SafeHandleC2NHelper(Object pThis, IntPtr pCleanupWorkList) 
at JulMar.Atapi.Interop.NativeMethods.lineGetCallStatus(HTCALL hCall, IntPtr lpCallStatus) 

我追溯到幾個電話,認爲問題的根源是以下調用本機功能Tapi32.dll:

int rc = NativeMethods.lineMakeCall(Line.Handle, out hCall, address, countryCode, lpCp); 

(定義在TAPI在這裏:http://msdn.microsoft.com/en-us/library/ms735988(VS.85).aspx

64位的hCall值是「0」,而在32位它是一個5位數的句柄。其他參數的值看起來不錯,在兩個平臺上都是相同的。

我的猜測是問題的一部分是與所述Line.Handle,這是自SafeHandle導出並在庫中的定義如下:

[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] 
internal class HTLINE : SafeHandle 
{ 
    internal HTLINE() 
     : base(IntPtr.Zero, true) 
    { 
    } 

    internal HTLINE(IntPtr preexistingHandle, bool ownsHandle) 
     : base(preexistingHandle, ownsHandle) 
    { 
    } 

    protected override bool ReleaseHandle() 
    { 
     if (handle != IntPtr.Zero) 
     { 
      NativeMethods.lineClose(handle); 
      handle = IntPtr.Zero; 
     } 
     return true; 
    } 

    public override bool IsInvalid 
    { 
     get { return handle == IntPtr.Zero; } 
    } 
} 

底層手柄是一個IntPtr並且由於它的不同大小在32位和64位,我認爲這可能會導致一個問題,如果TAPI預期只有4個字節在32位。爲了測試這個理論,我正在考慮創建一個不使用IntPtr的句柄。這聽起來像一個合理的方法?

感謝您的任何建議。

+1

簡單的解決方案是,如果Atapi庫不適用於64位IntPtr,那麼您應該發送一個32位值。一旦你收到的值將其轉換爲IntPtr。當然,它不工作的事實聽起來像庫中的錯誤,因爲IntPtr是執行SafeHandles的正確方法。您可以通過將應用程序設置爲32位應用程序(即使在x64操作系統上)來實現此操作 –

+0

由於操作系統句柄是IntPtr,因此您的操作系統錯誤。 SafeHandle只是它的一個包裝。在ReleaseHandle()方法上設置斷點以確保句柄不會太快釋放。但更可能的是TAPI本身,它做得不好。我肯定會避免嘗試在64位模式下使用它。 –

+0

感謝您的反饋。 ReleaseHandle()不會被過早釋放,事實上,導致錯誤的句柄(HTCALL)在創建時標記爲Closed且無效,因爲它傳遞的hCall值爲0. hCall在Atapi中定義爲IntPtr, lineMakeCall函數應該爲其賦值。我會盡力找到另一種解決方法。 – DeltaVax

回答

0

我在.net 3.5(mscorlib是32位)上遇到了同樣的問題,在這種情況下,julmar ATAPI必須編譯爲x86,任何CPU或x64都不適用於64位操作系統。

我沒有支持mscorlib 64位的dotnet 4.0,所以我無法進一步調試,我唯一的選擇是x86。

有關信息,TSP將需要64位系統上的64位版本。