簡體   English   中英

哪種方法更好:Process.Start或直接調用DLL?

[英]Which approach better: Process.Start or call DLL directly?

在我們的團隊中,我們面臨着這樣的選擇:我們需要調用外部第三方代碼並從C#代碼處理其輸出。

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

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

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

一方面調用dll看起來更正確的方式來完成這項工作,但另一方面 - 為本機C代碼中的所有函數提供C#綁定可能真的很復雜。

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

這將非常有用!

編輯 :我在談論這個特殊情況下的視頻轉換。 我需要從用戶那里獲取視頻流並將其轉換為一種視頻格式。 可以調用ffmpeg來完成這項工作,一切正常,直到出現問題,我需要重新開始編碼或采取任何行動。 我無法估計需要多長時間,如果我需要並行轉換幾個視頻, ffmpeg將不會那么靈活,因為我計划它......

至少我現在看到了。 當我深入研究時,可能會出現更多問題。

有幾個注意事項:

  1. 你有dll的來源嗎?
  2. 你打算打電話給那些dll多少錢?
  3. dll的API和你的用法有多復雜?

取決於答案。

如果創建綁定:

  • 你會經常打電話給dlls。 直接呼叫要快得多。
  • 你有來源並檢查它們有多好。 否則,您可能會遇到內存泄漏,調用約定等問題。
  • dll的API不是太復雜,所以你不需要向它們發送C ++對象等。或者在exe中完成很多工作。

使用可執行文件:

  • 如果您只是偶爾需要運行它們。 創建另一個流程的開銷對您來說無關緊要。
  • 如果你不確定代碼的質量。 它將為您的代碼提供更安全和可靠的功能,而不是加載一些執行不當的dll。 如果出現問題,您可以嘗試多次運行.exe。 但它是一個dll崩潰你的應用程序,你不能做任何事情。
  • 如果API非常復雜,並且exe具有很多功能,那么您將不得不重新實現。

我想這將取決於您的代碼在庫的api支持方面所期望的粒度。

如果可執行文件能夠很好地封裝工作流,那么您可以從調用可執行文件的簡單性中受益。

此外,既然你提到這是本機C代碼,添加DLL引用意味着必須處理非托管代碼,除非我沒有選擇,否則我個人不會這樣做。

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

我說這一切都取決於你的要求,時間框架, exe文件輸出的穩定性,以及解析它的容易程度。 兩種方式都是可行的。

例如,Mercurial認為它的控制台輸出是與它交互的主要方式 - 即使可以直接使用它的Python代碼。

另一方面,從C#調用C函數相當容易,因此這也是一個選項。 但是,如果您需要映射數百個C函數,則必須問自己是否有時間這樣做。

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並使用編組將參數映射到.net類型

答案取決於外部應用程序使用它的方式:

  • 調用exe,如果它多次調用多個dll函數,並且其業務流程又大又復雜 - 您不希望在C#代碼中重新實現所有exe邏輯。
  • 直接調用dll,如果exe只調用dll中的兩個函數,則調用順序和參數是眾所周知的或根本不存在。

我一般,我更喜歡直接調用dll,因為這消除了產生新進程和處理其輸出的大量開銷和可能的問題。 並且不要害怕本機代碼,如果您的dll函數很簡單,那么使用PInvoke,您將能夠輕松調用這些函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM