2012-06-07 72 views
6

在我們的項目中,我們在asp.net應用程序中通過COM重用了很多Delphi代碼。爲什麼COM Interop比.NET中的P/Invoke更受歡迎?

像這樣:傳統的德爾福DLL => Delphi的COM包裝=> .NET互操作程序=> asp.net(MVC)

我們有關於訪問衝突,dll的卸載等一些問題......我有現在移植一些直接通過P/Invoke代碼使用遺留的dll。

當我查看有關COM和P/Invoke的資源時,人們幾乎總是建議使用COM。這是爲什麼?不會的P/Invoke具有以下優點:

  • 簽出代碼總是會使用正確的DLL,而不是最後的註冊COM
  • 多個版本可以在服務器上並行運行(例如:DEV,測試和QA)
  • 沒有更多的COM註冊的麻煩
  • 比COM通訊(文章我讀指示的速度提高了30%)要快得多
+0

你可以從64位進程p/invoke到一個32位的DLL?我不這麼認爲。 – Bond

+1

你可以給一些建議COM建議P/Invoke嗎?我非常同意你的看法,P/Invoke是更好的解決方案。 .NET BCL中的大部分內部都是通過對Win32 API的P/Invoke實現的。只有使用COM互操作的理由是你沒有選擇的地方,例如與Office應用程序互操作,或僅COM的Windows API部件。 – Govert

+0

記住DLL地獄?代替使用正確的DLL,您的代碼將使用第一個可用的dll具有相同的名稱。直到運行時纔會檢測到任何API更改,這意味着版本控制幾乎不可能。你不能創建一個能夠同時爲新舊客戶端提供服務的DLL,而不必改變這些函數本身的名字 –

回答

8

PInvoke的是一個非常好的工具,但可以肯定的是ñ o替代COM。 Pinvoke只支持具有C語法的簡單函數,COM允許您實現對象模型。以Microsoft.Office.Interop命名空間中的類爲例,它們都是純粹的沒有包裝的COM類。與pinvoke做互操作將會非常痛苦。

另一個核心問題是,它通常是客戶端程序員編寫聲明的負擔。最不可能讓他們正確的人。 COM作者可以發佈自動生成的類型庫,就像.NET程序集中的元數據一樣。極大地消除了錯誤的可能性,並且除了Project + Add Reference之外,客戶端程序員無需任何工作。

解決你的子彈:

  • 簽出代碼總是會使用最後的註冊COM
    正確的DLL,而不是你仍受到到Windows中找到適當的DLL變幻莫測。避免意外的唯一好方法是將DLL存儲在與EXE相同的目錄中。這是在COM很可能的,你所要做的就是創建一個空文件名稱爲yourapp.exe.local

  • 多個版本可以在服務器上並行運行(例如:開發,測試和QA)
    使用上述技術或通過使用免註冊清單,COM中也不存在問題

  • 沒有更多COM註冊麻煩
    使用免註冊清單,因此不需要註冊。很簡單,只需將引用的Isolated屬性設置爲True即可。

  • 比COM通訊更快(我讀的文章指出的速度提高了30%)
    它比COM多。通過IDispatch進行遲到的COM調用可能會產生額外的成本,這與撥打電話的費用大致相當。


還有第三個辦法做到本地代碼互操作:寫在C++/CLI語言的託管類包裝。在.NET框架中大量使用的技術,尤其是在mscorlib.dll,System.Data和PresentationFramework中,對本機代碼具有強依賴性的程序集。對於Delphi來說,它並不是非常適合,它最適用於可以輕鬆地從C或C++調用的本地代碼。

+0

很棒的回答。我嘗試了一個無reg的清單,但無法使其運行,至少不能從Visual Studio(孤立屬性)中運行。我不知道「yourapp.exe.local」如何改變查找正確COM的行爲? – Cohen

+0

我不知道如何回答「這不行」的問題。 .local文件只是告訴Windows加載程序僅查看包含EXE的目錄,而不考慮註冊表項中指定的路徑。原油,並沒有替代清單,但它肯定可以得心應手。 –

+0

「'它不起作用' - 問題。」我明白。我將不得不更多地查看清單文件。我不認爲.local會成爲asp.net環境中的解決方案。如果我沒有弄錯的話,這個例子中的exe就是IIS工作進程。 – Cohen

相關問題