为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
变量。
我尝试通过 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
变量。