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

Can I use libraries written in a different language than my program?

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

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

我正在浏览 GitHub 寻找潜在的解决方案,其中很多似乎都使用了 FFmpeg 库,我想知道这怎么可能(如果)这些库是用不同的语言。谢谢

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及其函数的名称。

要使用它,您需要使用 [DllImport(...)] 属性声明一个 extern 方法,并小心使用正确的参数类型等。这是来自 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(据我所知),因此这两个选项都不可用。如果该库在适合 linking 到 C++ 程序的库中可用,那么您要做的就是编写一个 Interop 程序集,基本上是在 C++ 中创建 .NET 类 来弥合差距您要使用的 ffmpeg 库。由于 C++.NET 项目既可以 link 这样的库,也可以生成 .NET 程序集,这可以做到,但需要再次仔细注意所涉及的类型。

我假设有人已经完成了这项工作并且 scouring nuget.org 找到了这些 nuget 包:

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

最后,如果您使用的是 .NET Core,并且需要在 Linux 上执行此操作,则需要执行与上述 Windows DLL 相同的操作,除了 . Linux 上的 NET Core 可以向 .so 文件添加类似类型的引用。但是,如果您要 link 的库不是独立库但适合 linking.

,则上面编写的有关互操作程序集的所有内容仍然有效

另请注意,创建 一个 程序集同时适用于 Windows 和 Linux 也是一项艰巨的任务。


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

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

您可以在 Stack Overflow 上阅读更多关于这一行攻击的信息,Execute ffmpeg command with C#