2013-01-24 132 views
7

在我們的團隊中,我們面臨着選擇:我們需要調用外部第三方代碼並處理來自C#代碼的輸出。哪種方法更好:Process.Start或直接調用DLL?

第三方代碼有兩種形式:一組dll s和一個exe文件(可能自己調用​​這些dll s)。可能的方法可能是:使用Process.Start語句來運行可執行文件並捕獲其輸出。另一個是直接撥打dll

我想了解我們應該使用哪種方法。

一方面調用可執行文件很簡單,但另一方面 - 它感覺不健壯。

一方面呼籲dll看起來做的工作更正確的方式,但另一方面 - 這可能是非常複雜的任務提供C#因爲我們有本地C代碼的所有功能結合。

但是我需要對此主題進行更實質性的分析才能做出最終決定。以前有沒有人面對同樣的問題,也許你可以分享你的發現。

這將是非常有用的!

編輯:我在說這個特殊情況下的視頻轉換。我需要從用戶獲取視頻流並將其轉換爲所有視頻格式。可以撥打ffmpeg來完成這項工作,並且一切正常,直到出現問題,我需要重新啓動編碼或採取任何行動。我不能估計需要多長時間,如果我需要並行轉換幾個視頻ffmpeg將不會那麼靈活,因爲我計劃它是...

至少我現在看到它。也許更多的問題會出現,因爲我深入研究。

+1

你需要提供更多的細節...和:你有什麼嘗試?你做了什麼測試?是否有任何依賴關係(如COM或USB /驅動程序或權限等)?有不穩定嗎?您需要哪種級別的控制/粒度/性能? – Yahia

回答

4

有幾方面的考慮:

  1. 你有dll的來源是什麼?
  2. 你打算稱這些dll多少錢?
  3. dll的API和您的使用情況有多複雜?

根據答案。

創建綁定,如果:

  • 你會經常致電的DLL。直接通話要快得多。
  • 你有來源,並檢查他們有多好。否則,你可能會遇到內存泄漏,調用約定等問題。
  • dll的API不是太複雜,所以你不需要發送C++對象給它們,等等。或者我們已經在exe中做了很多工作。

使用可執行文件:

  • 如果需要只是偶爾運行它們。創建另一個流程的開銷對你無關緊要。
  • 如果您不確定代碼的質量。它對你的代碼來說更安全和健壯,而不是加載一些執行得不好的dll。如果發生問題,您可以嘗試多次運行.exe。但它會崩潰你的應用程序,你什麼都做不了。
  • 如果API非常複雜,並且exe有很多功能,那麼您將不得不重新實現。
+0

只需添加到此答案中,也是可執行文件啓動時間的一個因素。如果它是一個維護狀態&c的程序。那麼在每次通話中支付啓動費用可能都不合意。 –

0

我想說這將取決於多少粒度,你的代碼期望在庫支持api方面。

如果可執行文件足以爲您封裝工作流程,則可以從調用可執行文件的簡單性中受益。另外,由於您提到的是本機C代碼,因此添加DLL引用意味着必須處理非託管代碼,除非沒有我的選擇,否則我個人不會這樣做。

0

如果dll編寫得很好,並且沒有內存泄漏,最好使用dll,因爲它不需要新的進程創建開銷。

0

我想說這一切都取決於您的要求,時間範圍,您的exe文件輸出的穩定性,以及它可以被輕鬆解析。這兩種方式都是可行的。

例如,Mercurial認爲它的控制檯輸出是與它交互的主要方式 - 儘管可以直接使用它的Python代碼。另一方面,從C#調用C函數相當容易,所以這也是一種選擇。但是,如果您需要映射數百個C函數,則必須問自己是否有時間這樣做。

0

EXE 有一個主要條目被調用,所以你不能直接調用函數。 當您調用一個exe時,將創建一個新進程 在該進程的主線程的上下文中調用入口線程。

DLL 爲您提供了更大的靈活性,通過調用函數直接 每個函數的入口點 系統加載DLL到現有線程的上下文

因此調用DLL是多的計算資源更好,並提供更具流動性。考慮到你可以從託管和非託管代碼調用DLL,並且可以從C#調用託管和非託管dll:

如果DLL有一個接口,你可以直接添加一個參考,如果沒有,你仍然可以調用它像下面

[DllImport(@"TestLib.dll")] 
    public static extern void InitParam([MarshalAs(UnmanagedType.LPWStr)] string inputFile, 
     [MarshalAs(UnmanagedType.LPWStr)] string outputFile, 
     [MarshalAs(UnmanagedType.LPWStr)] string templateFile, 
     [MarshalAs(UnmanagedType.LPWStr)] string userName, 
     [MarshalAs(UnmanagedType.LPWStr)] string manifestFilePath, 
     [MarshalAs(UnmanagedType.LPWStr)] string usersRightList); 
簡單的話

導入DLL和使用編組

0

答映射參數.NET類型取決於外部應用程序使用它的dll文件:

    的方式
  • 如果多次調用多個dll函數並調用它的業務流程很複雜,那麼調用exe文件 - 您不希望重新實現C#代碼中的所有exe邏輯。
  • 直接調用dll,如果exe只調用dll中的一兩個函數,調用順序和參數是衆所周知或根本不存在的。

我一般,我寧願直接調用dll,因爲這消除了大量的開銷和可能產生的新進程和處理其輸出的問題。不要害怕本地代碼,如果你的dll函數很簡單,那麼使用PInvoke你就可以輕鬆地調用這些函數。

相關問題