我可以使用以与程序不同的语言编写的库吗?

时间:2020-10-15 05:41:46

标签: c# .net libraries desktop-application

我正在学习.NET框架,基本上我正在尝试制作一个将YouTube URL转换为mp3格式的桌面应用程序。我进行了一些研究,发现最好的选择是使用FFmpeg库。但这不是.NET库(不是用任何.NET语言编写的)。

所以,我的问题是我可以使用以其他语言编写的库吗?

我正在GitHub上浏览潜在的解决方案,其中许多似乎都使用FFmpeg库,而且我想知道(如果)库是用不同的语言编写的。谢谢。

1 个答案:

答案 0 :(得分:2)

TL; DR :是或否,这取决于库的类型。我建议您转到nuget.org,并查看已经为您完成所有工作的可用软件包。


一个完整的答案可能是关于一本书的价值,所以让我归纳为更易于管理的东西,至少是我所知道的东西。另外,请强调知道的东西

让我们避免专注于C#,而是专注于.NET,因为此答案或我将要写的方式在任何方面都特定于C#,而它们特定于.NET。

通常,您可以从.NET程序集中引用两种类型的外部库:

  • 其他.NET程序集
  • Windows DLL(稍后将进一步介绍Linux)

引用其他.NET程序集将在最终程序集中使用相同的技术(对此有引用),但是要实现该目标,您可以有几种选择:

  1. 您可以在同一个解决方案文件中创建同级.NET项目,并提供项目引用
  2. 您可以在Nuget包上添加依赖项
  3. 您可以直接引用磁盘上的程序集文件

这3个选项最终都将嵌入对相关程序集的引用。这只是您引用的普通.NET代码,因此这里没有神奇的事情发生。您几乎可以肯定已经这样做了。

现在,对于Windows DLL,即不是.NET程序集的.dll文件,您需要执行其他操作。

您需要使用 P / Invoke ,该名称基本上是如何引用此类DLL及其功能的名称。

要使用此方法,您需要使用extern属性声明一个[DllImport(...)]方法,并小心使用正确的参数类型,依此类推。这是来自PInvoke.net的示例:

[DllImport("gdi32.dll")]
static extern bool ArcTo(IntPtr hdc, int nLeftRect, int nTopRect,
   int nRightRect, int nBottomRect, int nXRadial1, int nYRadial1,
   int nXRadial2, int nYRadial2);

正确编写外部方法需要仔细注意所涉及的数据类型。除非这是您唯一的选择,否则我建议您尝试使用nuget路径。


现在,ffmpeg既不是.NET程序集也不是Windows DLL(据我所知),因此这两个选项都不可用。如果该库在适合链接到C ++程序的库中可用,那么您要做的就是编写一个Interop程序集,基本上是用C ++创建.NET类,以将差距缩小到您要使用的ffmpeg库。由于C ++。NET项目既可以链接到此类库,也可以生成.NET程序集,因此可以做到这一点,但同样需要对所涉及的类型进行仔细的关注。

我认为有人已经完成了这项工作,scouring nuget.org出现了这些nuget包:

我的建议是去检查这些nuget软件包。由于ffmpeg包含多个具有不同用途的库,因此您需要找到一个可以访问您感兴趣的库的库。

最后,如果您使用的是.NET Core,并且需要在Linux上执行此操作,则您将需要执行与上述Windows DLL相同的操作,只是Linux上的.NET Core可以添加类似类型的引用到.so个文件。但是,如果要链接到的库不是独立的库而是适合链接的,则上面编写的有关互操作程序集的所有内容仍然有效。

还要注意,创建在Windows和Linux上均可使用的 one 程序集也是一项艰巨的任务。


最后一个选择是,您可以使用ffmpeg命令行应用程序。您必须将要处理的数据作为文件存储在磁盘上,然后仔细构造命令行程序的所有参数,以这样的方式调用它:既捕获程序的输出又隐藏它,以便用户看不到控制台窗口,最后从最终文件中读取处理后的输出。

如果您找不到合适的nuget包并且不想花时间研究如何正确获取p / invoke或interop程序集,这是一种简单的方法,但在某种意义上讲可能有点挑剔真正地启动一个单独的程序并等待它完成,您可能必须解析文本输出以弄清楚执行过程中发生了什么,例如成功还是失败。

您可以在堆栈溢出Execute ffmpeg command with C#上了解有关此攻击路线的更多信息。