C#调用FFmpeg动态库
作者:罗上文,微信:Loken1,公众号:FFmpeg弦外之音
在 C# 里调用 FFmpeg 动态库是非常简单的,你只需要使用 DllImport() 函数导入 dll,然后给 dll 的函数一个声明就行,代码如下:
public class FFmepeg
{
[DllImport("avformat-58.dll", CharSet = CharSet.Auto)]
public static extern UInt32 avformat_version();
}
然后我们就能在 main() 函数里面调用 avformat_version() 里,如下:
namespace print_version
{
class Program
{
static void Main(string[] args)
{
UInt32 ver = FFmepeg.avformat_version();
Console.WriteLine("ffmpeg libavformat version is {0:D3}", ver);
}
}
}
完整的项目代码可以在下面的地址下载:
E:\0-博客\ffmpeg_principle_volume1\source\code\ffmpeg_csharp
C# 调 C 语言的函数,有一个问题需要注意,也就是数据类型的转化。其实也不能叫转化,而是这两种语言的数据类型的对应关系。如下:
| C++ Type | C# Type | Size |
|---|---|---|
| BOOL | bool | 1 byte |
| BYTE | byte | 1 byte |
| CHAR | byte | 1 byte |
| DECIMAL | Decimal | 16 bytes |
| DOUBLE | double | 8 byte |
| UINT, unsigned int | uint, UInt32 | 4 byte |
| ... | ... | ... |
更多数据类型的对应关系请看 displayfusion
avformat_version() 在 C 语言的返回值是 unsigned,如下:
unsigned avformat_version(void)
{
av_assert0(LIBAVFORMAT_VERSION_MICRO >= 100);
return LIBAVFORMAT_VERSION_INT;
}
所以我们在 C# 里面声明 avformat_version 的时候,要写成返回值是 UInt32 的类型。因为 C# 里面没有 unsigned 类型,只有 UInt32 类型。
public static extern UInt32 avformat_version();
上面介绍的是 C# 与 C 语言简单的数据类型对应的关系,但是我们知道 C 语言是可以自定义数据类型的,例如 AVPacket 就是一个自定义数据类型,如果在 C# 里面想使用 AVPacket 数据类型怎么办呢?
答:可以使用 CppSharp 把 C 的 API 转成 C# 的托管 API。我也不太清楚 CppSharp 这个开源项目的底层原理,反正能用就行了,读者有兴趣可以自行研究。
FFmpeg.AutoGen 就是使用了 CppSharp,把 FFmpeg 的 API 转成 C# 的 API,读者可以自己跑一下 FFmpeg.AutoGen。
不过我个人一般不太喜欢用 FFmpeg.AutoGen 这种方式,因为类型、API 转换太麻烦,感觉容易出问题。我平时需要实现什么功能,我直接用 C 语言写,然后封装成一个大函数,编译成 dll,让 C# 来调 dll 里面的大函数就行。这样比较方便。
思考:如何把 C# 的函数作为一个指针传递给 FFmpeg 调用?
TODO:你需要整理一下这本书的源代码。