如何从 C# 调用 ac 函数

发布于 2024-11-09 07:24:38 字数 214 浏览 0 评论 0原文

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

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

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

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

I would like to use this C function in C#:

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

How would I go about defining it so I can call it?

Do I need to do anything else to make this work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清风无影 2024-11-16 07:24:38

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

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

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

Take a look at http://msdn.microsoft.com/en-us/library/ektebyzx(v=vs.80).aspx for how to marshal function pointers. There is an example on the bottom of that page.

I'll do the C# for you, and since I don't know which direction the pointer is going, I'll show both. There are some gotchas which could be problematic for you involving calling conventions. Marshal.GetDelegateForFunctionPointer and Marshal.GetFunctionPointerForDelegate assume the function pointer will be StdCall so if you don't have access to the unmanaged library to make sure the function pointer is standard call (I think C defaults to cdecl unfortunately), you'd have to create an unmanaged shim library to change the calling convention, unless there is some other way I don't know about.

This would be the header of a C DLL I named "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);
}

This would be the CPP file of the 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);
}

And lastly, this is a C# program to make use of the 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));
    }
}
神魇的王 2024-11-16 07:24:38

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

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

That looks like more of a delegate than a function/method itself. You wouldn't call this, this would be supplied as a function pointer to something else. The equivalent might be something like this:

public delegate void WRITE_CALLBACK(int hMountEnv, uint numBytesWritten, object pContext);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文