Посмотрите на http://msdn.microsoft.com/en-us/library/ektebyzx(v=vs.80).aspx, как маршалировать указатели функций. Внизу этой страницы есть пример.
Я сделаю для вас C #, и, поскольку я не знаю, в каком направлении движется указатель, я покажу оба. Есть некоторые ошибки, которые могут быть проблематичными для вас в отношении соглашений о вызовах. Marshal.GetDelegateForFunctionPointer
и Marshal.GetFunctionPointerForDelegate
предполагают, что указатель функции будет StdCall, поэтому, если у вас нет доступа к неуправляемой библиотеке, чтобы убедиться, что указатель функции является стандартным вызовом (я думаю, что C по умолчанию использует cdecl, к сожалению), вам придется создайте неуправляемую библиотеку shim для изменения соглашения о вызовах, если не существует другого способа, о котором я не знаю.
Это будет заголовок C DLL, которую я назвал "UnmanagedLib.dll".
typedef void ( __stdcall *WRITE_CALLBACK)(int hMountEnv, unsigned __int64 NumBytesWritten, void* pContext);
extern "C" {
__declspec(dllexport) WRITE_CALLBACK __stdcall FunctionProducingFunctionPointer(void);
__declspec(dllexport) void __stdcall FunctionConsumingFunctionPointer(WRITE_CALLBACK callback);
}
Это будет файл CPP DLL.
#include "UnmanagedLib.h"
void __stdcall SampleFunction(int hMountEnv, unsigned __int64 NumBytesWritten, void* pContext)
{
}
WRITE_CALLBACK __stdcall FunctionProducingFunctionPointer(void)
{
return &SampleFunction;
}
void __stdcall FunctionConsumingFunctionPointer(WRITE_CALLBACK callback)
{
// sample call
(*callback)(0,0,NULL);
}
И, наконец, это программа на C # для использования DLL.
class Program
{
public delegate void WRITE_CALLBACK(int hMountEnv, ulong NumBytesWritten, IntPtr pContext);
[DllImport("UnmanagedLib.dll")]
public static extern IntPtr FunctionProducingFunctionPointer();
[DllImport("UnmanagedLib.dll")]
public static extern void FunctionConsumingFunctionPointer(IntPtr functionPointer);
public static void SampleFunction(int hMountEnv, ulong NumBytesWritten, IntPtr pContext)
{
}
static void Main(string[] args)
{
var functionDelegateToManagedSampleFunction = new WRITE_CALLBACK(SampleFunction);
var functionDelegateToUnmanagedSampleFunction = Marshal.GetDelegateForFunctionPointer(FunctionProducingFunctionPointer(), typeof(WRITE_CALLBACK));
// call the unmanaged sample function via its pointer
functionDelegateToUnmanagedSampleFunction.DynamicInvoke(new object[] {0,0ul,null});
// pass the managed sample function to the unmanaged code
FunctionConsumingFunctionPointer(Marshal.GetFunctionPointerForDelegate(functionDelegateToManagedSampleFunction));
}
}