IntPtr到回调函数

时间:2014-07-15 12:36:30

标签: c# c++ ffmpeg

我在C#中使用FFMPEG并具有以下函数prototpe:

public static extern AVIOContext* avio_alloc_context(byte* buffer, int buffer_size, int write_flag, void* opaque, IntPtr read_packet, IntPtr write_packet, IntPtr seek);

在C / C ++中,此函数声明如下:

avio_alloc_context (unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))

在C / C ++中,我可以执行以下操作来调用此函数:

int readFunction(void* opaque, uint8_t* buf, int buf_size)
{
    // Do something here
    int numBytes = CalcBytes();
    return numBytes;
}

int64_t seekFunction(void* opaque, int64_t offset, int whence)
{
   // Do seeking here
   return pos;
}

AVIOContext * avioContext = avio_alloc_context(ioBuffer, ioBufferSize, 0, (void*)(&fileStream), &readFunction, NULL, &seekFunction);

readFunctionseekFunction是用于阅读/搜索等的回调函数。

我不确定如何在代码的C#版本中复制此行为时需要IntPtr。如何创建回调函数并将它们传递给C#版本?

1 个答案:

答案 0 :(得分:2)

事实证明你可以做到这一点,但它并不完全直观。

首先,您需要使用UnmanagedFunctionPointer创建一个委托,并确保可以传递参数 使用[In, Out]

修改后,从被调用者返回调用者
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int av_read_function_callback(IntPtr opaque, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), In, Out] byte[] endData, int bufSize);

在函数中,我们可以编组此delegate,如下所示:

private av_read_function_callback mReadCallbackFunc;

mReadCallbackFunc = new av_read_function_callback(ReadPacket);

mAvioContext = FFmpegInvoke.avio_alloc_context(mReadBuffer, mBufferSize, 0, null, Marshal.GetFunctionPointerForDelegate(mReadCallbackFunc), IntPtr.Zero, IntPtr.Zero);

其中ReadPacket看起来像

public int ReadPacket(IntPtr opaque, byte[] endData, int bufSize)
{
    // Do stuff here
}

这导致与C ++中的函数指针相同的行为。