如何从C#调用c函数

时间:2011-05-20 20:36:49

标签: c# c callback

我想在C#中使用这个C函数:

typedef void (*WRITE_CALLBACK)(int hMountEnv, unsigned __int64 NumBytesWritten, 
               void* pContext);

我如何定义它以便我可以调用它?

我需要做任何其他事情才能使这项工作成功吗?

2 个答案:

答案 0 :(得分:1)

看看http://msdn.microsoft.com/en-us/library/ektebyzx(v=vs.80).aspx如何编组函数指针。该页面底部有一个例子。

我会为你做C#,因为我不知道指针的方向,我会同时展示。对于涉及调用约定的问题,有一些问题可能会有问题。 Marshal.GetDelegateForFunctionPointerMarshal.GetFunctionPointerForDelegate假设函数指针将是StdCall,所以如果你不能访问非托管库以确保函数指针是标准调用(我认为C默认为cdecl),你我必须创建一个非托管的填充程序库来更改调用约定,除非有其他我不知道的方法。

这将是一个名为“UnmanagedLib.dll”的C 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);
}

这将是DLL的CPP文件。

#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);
}

最后,这是一个使用DLL的C#程序。

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));
    }
}

答案 1 :(得分:1)

这看起来更像是一个委托,而不是一个函数/方法本身。你不会这称呼它,它将作为一个函数指针提供给其他东西。等价物可能是这样的:

public delegate void WRITE_CALLBACK(int hMountEnv, uint numBytesWritten, object pContext);