我在C#中使用FFMPEG,并具有以下功能原型:
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);
其中readFunction
和seekFunction
是用于读取/查找等的回调函数。
我不知道如何在代码的C#版本中复制这种行为,因为它需要一个IntPtr
。如何创建回调函数并在C#版本中传递它们?
发布于 2014-07-16 06:47:49
事实证明,你可以做到这一点,但这并不完全是直观的。
首先,您需要使用UnmanagedFunctionPointer
创建一个委托,并确保在使用[In, Out]
进行修改后,可以将params从被调用方传递回调用方。
[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++中的函数指针相同的行为。
https://stackoverflow.com/questions/24758386
复制