【问题标题】:Can I use libraries written in a different language than my program?我可以使用以与我的程序不同的语言编写的库吗?
【发布时间】:2021-01-29 13:54:03
【问题描述】:

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

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

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

【问题讨论】:

  • 这个问题很老,但也有一些相对较新的答案。也许它可以让你开始。 stackoverflow.com/questions/2527963/using-ffmpeg-in-net这是另一个:stackoverflow.com/questions/2163036/…
  • 我认为这是一个完全有效的问题,我无法立即找到重复项。为什么关门了?
  • 我之前通读了那些,但我只是变得更加困惑。我会更多地研究包装器。感谢您的洞察力。也许我的问题太天真了,但我不知道。
  • My main question is can I use a library that is written in a different language? 简单的答案是“是”。 C# 可以使用 VB.NET 库,作为一个简单的例子。
  • I read through those previously but I only got more confused. 如果您阅读过这些内容,那么您就会知道答案——它可以做到。可以!= 很容易,唉。

标签: c# .net libraries desktop-application


【解决方案1】:

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(据我所知),因此这两个选项都不可用。如果该库在适合链接到 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 上都可以工作的一个程序集也是一项艰巨的任务。


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

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

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

【讨论】:

  • 这很有意义。我非常感谢您提供如此详细且措辞良好的解释。我现在正在前往互操作程序集的路上!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 2017-03-26
相关资源
最近更新 更多