为NULL时通过P/Invoke传递双指针参数

Pass double pointer parameter through P/Invoke when it is NULL

我尝试通过 P/Invoke

调用 FFMPEG 方法
 int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);

所以我的 P/Invoke 方法定义如下:

[DllImport("avformat-55", EntryPoint = "avformat_find_stream_info", CallingConvention = CallingConvention.Cdecl)]
    public extern static int AVFormatFindStreamInfo(IntPtr ic, ref IntPtr options);

我需要为选项传递一个 IntPtr.Zero,所以我这样调用:

var p = IntPtr.Zero;
rst = AVFormatFindStreamInfo(context, ref p);

并引发 AccessViolation 异常。

但是当我从签名中删除 ref,并直接将 IntPtr.Zero 传递给它时,它确实有效。 我认为带ref关键字的签名是正确的方式,但我不知道为什么会抛出异常。

你不能用

做到这一点
ref IntPtr options

这也会将 IntPtr 变量的地址传递给非托管代码。该地址永远不能是 NULL。如果您需要能够将 NULL 传递给非托管代码,则必须

IntPtr options

你通过了IntPtr.Zero

您可以使用两个重载来执行此操作。一种是在您想要接收选项对象时使用的,另一种是在您不想接收选项对象时使用的。或者,您可以使用单个重载,即此答案中的版本,并在需要接收选项变量时手动固定 IntPtr 变量。