如何从 C# 调用 c 函数

本文关键字:函数 调用 | 更新日期: 2023-09-27 17:57:01

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

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

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

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

如何从 C# 调用 c 函数

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

我将

为您执行 C#,由于我不知道指针朝哪个方向移动,因此我将同时显示两者。有一些陷阱可能会给您带来问题,涉及调用约定。 Marshal.GetDelegateForFunctionPointerMarshal.GetFunctionPointerForDelegate假设函数指针将是 StdCall,因此如果您无权访问非托管库以确保函数指针是标准调用(我认为 C 默认为 cdeccl不幸的是),您必须创建一个非托管填充码库来更改调用约定,除非有我不知道的其他方式。

这将是我命名为"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));
    }
}

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

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