I am using FFMPEG in C# and have the following function 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);
In C/C++ this function is declared as follows:
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))
In C/C++ I can do the following to call this function:
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);
Where the readFunction
and seekFunction
are callback functions that are used in reading/seeking etc.
I am unsure how to copy this behaviour in the C# version of the code when it expects an IntPtr
. How can I create the callback functions and pass them in the C# version?
Turns out you can do this, however it is not entirely intuitive.
First you need to create a delegate with the
UnmanagedFunctionPointer
and ensure the params can be passed back from the callee to the caller after being modified using[In, Out]
In the function we can then marshal this
delegate
as follows:where
ReadPacket
looks something likeThis results in the same behaviour as a function pointer in C++.