Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 哪种方法更好:Process.Start或直接调用DLL?_C#_Dll_Native_Exe_Process.start - Fatal编程技术网

C# 哪种方法更好:Process.Start或直接调用DLL?

C# 哪种方法更好:Process.Start或直接调用DLL?,c#,dll,native,exe,process.start,C#,Dll,Native,Exe,Process.start,在我们的团队中,我们面临着这样的选择:我们需要调用外部第三方代码,并从C#代码处理其输出 第三方代码有两种形式:一组dlls和一个exe文件(它可能自己调用这些dlls)。可能的方法是:使用Process.Start语句运行可执行文件并捕获其输出。另一种是直接调用dll 我正在试图了解我们应该使用哪种方法 一方面调用可执行文件很简单,但另一方面,它感觉不健壮 一方面,调用dll看起来更适合做这项工作,但另一方面,为原生C代码中的所有函数提供C绑定可能是一项非常复杂的任务 但我需要对这个话题进行更

在我们的团队中,我们面临着这样的选择:我们需要调用外部第三方代码,并从C#代码处理其输出

第三方代码有两种形式:一组
dll
s和一个
exe
文件(它可能自己调用这些
dll
s)。可能的方法是:使用
Process.Start
语句运行可执行文件并捕获其输出。另一种是直接调用
dll

我正在试图了解我们应该使用哪种方法

一方面调用可执行文件很简单,但另一方面,它感觉不健壮

一方面,调用
dll
看起来更适合做这项工作,但另一方面,为原生
C
代码中的所有函数提供
C
绑定可能是一项非常复杂的任务

但我需要对这个话题进行更实质性的分析,才能做出最终决定。以前是否有人遇到过同样的问题,也许你可以分享你的发现

这将是非常有用的

编辑:在这种特殊情况下,我谈论的是视频转换。我需要从用户那里获取视频流,并将其转换为一种视频格式。可以调用
ffmpeg
来完成这项工作,一切正常,直到出现问题,我需要重新启动编码或采取任何措施。我无法估计需要多长时间,如果我需要并行转换多个视频,
ffmpeg
将不会像我计划的那样灵活


至少在我现在看来是这样。随着我的深入,可能会出现更多的问题。

我想说,这取决于您的代码在库的api支持方面所期望的粒度

如果可执行文件对工作流的封装足够好,则可以从调用可执行文件的简单性中获益


另外,由于您提到这是本机C代码,添加DLL引用将意味着必须处理非托管代码,除非我没有选择,否则我个人不会处理非托管代码。

如果DLL编写良好且没有内存泄漏,则最好使用DLL,因为它不需要新的进程创建开销。

我认为这一切都取决于您的需求、时间范围、您的
exe
文件的输出有多稳定,以及解析它的容易程度。这两种方法都是可行的

例如,Mercurial将其控制台输出视为与之交互的主要方式,尽管可以直接使用其Python代码

另一方面,从C#调用C函数相当容易,因此这可能也是一种选择。但是,如果您需要映射数百个C函数,您必须问问自己是否有时间这样做。

EXE 只有一个主条目需要调用,因此不能直接调用函数。 调用exe时,将创建一个新进程 入口线程在该进程的主线程上下文中被调用

动态链接库 通过直接调用函数为您提供了更大的灵活性 每个函数都有一个入口点 系统将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类型。答案取决于外部应用程序使用其DLL的方式:

  • 调用exe,如果它多次调用多个dll函数,并且其业务流程又大又复杂-您不想在C代码中重新实现所有exe逻辑
  • 直接调用dll,如果exe仅从dll调用一个或两个函数,则调用顺序和参数是众所周知的,或者根本不存在

一般来说,我更倾向于直接调用dll,因为这消除了大量开销以及产生新进程和处理其输出时可能出现的问题。不要害怕本机代码,如果您的dll函数很简单,那么使用PInvoke,您将能够轻松调用这些函数。

有几个注意事项:

  • 你有DLL的来源吗
  • 你打算给那些DLL打多少电话
  • DLL的API有多复杂,您的使用情况如何
  • 根据答案的不同

    在以下情况下创建绑定:

    • 您将经常调用DLL。直拨电话快得多
    • 你有来源并检查它们有多好。否则,您可能会遇到内存泄漏、调用约定等严重问题
    • 使用可执行文件:

      • 如果您只需要偶尔运行它们。创建另一个进程的开销对您来说并不重要
      • 如果您不确定代码的质量。对于您的代码来说,它将更加安全和健壮,而不是加载一些实现糟糕的dll。如果出现问题,您可以尝试多次运行.exe。但是如果dll崩溃了你的应用程序,你什么都做不了
      • 如果API非常复杂,并且exe有很多功能,则必须重新实现

      您需要提供更多详细信息。。。还有:你试过什么?你做过测试吗?是否存在任何依赖项(如COM或USB/驱动程序或权限等)?是否存在不稳定性?您需要哪一级别的控制/粒度/性能?只需添加到这个答案中,还需要考虑可执行文件的启动时间。如果它是一个维护状态&c的程序。那么,支付每次通话的启动费用可能并不可取。