在我们的团队中,我们面临着这样的选择:我们需要调用外部第三方代码并从C#代码处理其输出。
第三方代码有两种形式:dll
和单exe
文件集(可能单独调用这些dll
)。可能的方法可能是:使用Process.Start
语句来运行可执行文件并捕获其输出。另一个是直接致电dll
。
我试图了解我们应该使用哪种方法。
一方面调用可执行文件很简单,但另一方面 - 它感觉不健壮。
一方面调用dll
看起来更正确的方式来完成这项工作,但另一方面 - 为我们在本机{{1}中的所有函数提供C#
绑定可能真的很复杂。代码。
但是我需要对这个主题进行更实质性的分析才能做出最终决定。以前是否有人面对同样的问题,也许你可以分享你的发现。
这将非常有用!
编辑:我在谈论这种特殊情况下的视频转换。我需要从用户那里获取视频流并将其转换为一种视频格式。可以调用C
来完成这项工作,在出现问题之前一切正常,我需要重新开始编码或采取任何行动。我无法估计需要多长时间,如果我需要并行转换多个视频ffmpeg
将不会那么灵活,因为我计划它......
至少我现在看到了。当我深入研究时,可能会出现更多问题。
答案 0 :(得分:4)
有几个注意事项:
取决于答案。
在以下情况下创建绑定:
使用可执行文件:
答案 1 :(得分:0)
我想这将取决于您的代码在库的api支持方面所期望的粒度。
如果可执行文件能够很好地封装工作流,那么您可以从调用可执行文件的简单性中受益。
此外,既然你提到这是本机C代码,添加DLL引用意味着必须处理非托管代码,除非我没有选择,否则我个人不会这样做。
答案 2 :(得分:0)
如果dll写得很好且没有内存泄漏,那么最好使用dll,因为它不需要新的进程创建开销。
答案 3 :(得分:0)
我说这一切都取决于您的要求,时间范围,exe
文件输出的稳定程度以及解析的容易程度。两种方式都是可行的。
例如,Mercurial认为它的控制台输出是与它交互的主要方式 - 即使可以直接使用它的Python代码。
另一方面,从C#调用C函数相当容易,因此这也是一个选项。但是,如果你需要映射数百个C函数,你必须问问自己是否有时间这样做。
答案 4 :(得分: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并使用编组
将参数映射到.net类型答案 5 :(得分:0)
答案取决于外部应用程序使用它的方式。:
我一般情况下,我更喜欢直接调用dll,因为这消除了产生新进程和处理其输出的大量开销和可能出现的问题。并且不要害怕本机代码,如果您的dll函数很简单,那么使用PInvoke就可以轻松调用这些函数。