2010-09-07 73 views
4

我正在使用.net框架工作已經很好。在這段時間有一些情況,我使用P/Invoke來處理託管代碼無法做到的事情。使用P/Invoke的缺點是什麼

但是我從來不知道使用它的真正缺點是什麼。這也是我試圖儘可能不使用它的原因。

如果我谷歌,那麼我找到各種關於它的帖子,一些繪製災難性的圖片,並建議永遠不要使用它。使用一個或多個P/Invoke調用的應用程序的主要缺點和問題以及它們何時適用。 (不是從性能的角度來看,更多的方式是「無法從網絡共享中執行」)?

+0

我想指出,我從來沒有製作過一次沒有使用P/Invoke的生產應用程序。 – Gabe 2010-09-08 07:31:09

回答

13
  1. 管理/非託管類型之間編組有額外的開銷
  2. 不處於中等信任
  3. 不太直觀的工作,並可能導致微妙的錯誤就像漏水的手柄,破壞內存,...
  4. 這可能需要一些時間之前得到它的權利看着導出的C函數
  5. 問題時,當migrating from x86 to x64
  6. 當索姆出錯了,你不能簡單地進入非託管代碼來調試並理解你爲什麼會遇到異常。你甚至不能在反射器中打開它:-)
  7. 限制跨平臺的互操作性(即:如果你依賴Windows平臺的庫,你不能在Linux下運行)。

結論:只有在沒有託管替代方案時才使用,或者在只存在非託管庫的性能關鍵型應用程序中使用,以提供所需的速度。

+0

7.刪除跨平臺的互操作性(即:您不能移植到單聲道)。 – 2010-09-08 06:33:29

+0

@邁克爾,隨時編輯我的帖子,包括這個好建議。 – 2010-09-08 06:34:18

+0

@Darin - 完成:) – 2010-09-08 06:42:17

4

有三種不同的使用P/Invoke的場景,每種場景都有不同的缺點(或不這樣做)。

  1. 您需要使用.NET Framework中未提供的Windows功能。你唯一的選擇是P/Invoke,你所承受的缺點是現在你的應用只能在Windows上工作。

  2. 您需要使用由其他人提供給您的C風格的DLL,並且沒有相應的託管對象。現在你必須在你的應用程序中部署DLL,並且你在編寫函數的聲明(例如IntPtr/int),字符串編組以及人們覺得困難的其他事情時會遇到編組時間和可能出現的問題。

  3. 您有一些您編寫或控制的舊本機代碼,您想從託管代碼訪問它,而無需移植它。這裏有(2)的所有問題,但是你可以選擇移植它。我要斷言,通過移植它會比P/Invoking引起更多的錯誤。如果您正在移植的代碼會對本地代碼(如CRT)進行大量調用,那麼您可能還會導致更大的性能問題。

我的底線是,雖然P/Invoke不是微不足道的,告訴人們避免它是壞建議。一旦擁有正確的版本,運行時編組成本將保持不變。這些可能會少於您移植代碼時獲得的運行時成本。