首页 > 解决方案 > 我可以使用以与我的程序不同的语言编写的库吗?

问题描述

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

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

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

标签: c#.netlibrariesdesktop-application

解决方案


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 程序集,因此可以这样做,但需要再次注意涉及的类型。

我会假设有人已经完成了这项工作,并且搜索 nuget.org发现了这些 nuget 包:

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

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

另请注意,创建一个可在 Windows 和 Linux 上运行的程序集也是一项艰巨的任务。


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

如果您找不到正确的 nuget 包并且不想花时间研究如何正确获取 p/invoke 或互操作程序集,这是一种简单的方法,但在您真正开始一个单独的程序并等待它完成,您可能必须解析文本输出以找出执行期间发生的情况,例如它是成功还是失败。

您可以在 Stack Overflow, Execute ffmpeg command with C#上阅读有关此攻击线的更多信息。


推荐阅读