将 C# 函数指针传递到 C++/CLI 互操作 dll

Posted

技术标签:

【中文标题】将 C# 函数指针传递到 C++/CLI 互操作 dll【英文标题】:Passing C# function pointers into C++/CLI interop dll 【发布时间】:2011-11-23 18:32:55 【问题描述】:

我正在尝试将函数指针从 C# 传递到 C++/CLI,并得到一个 Windows 编译器错误,指出该语言 (C#) 不支持 ManagedTakeCallback 函数——我在C++/CLI 互操作。我的代码看起来像

C# 应用程序:

namespace ManagedConsoleApplication



class Callback
    
        public delegate double DelegateAdd(double value1, double value2);

        public static double CallbackAdd(double value1, double value2)
        
            return value1 + value2;
        

        public static DelegateAdd delegateCallback = new DelegateAdd(Callback.CallbackAdd); //declare as static to prevent GC

    

    class Program
    
       // [DllImport("InteropDLL.dll", CallingConvention = CallingConvention.StdCall)]
       // public static extern void ManagedCallback(IntPtr pCallback);
        static void Main(string[] args)
        
            InteropDLL io = new InteropDLL(); 
            Console.WriteLine("The Add return = 0", io.ManagedAdd(3, 2));
            Console.WriteLine("Pass CallBack to Unmanaged code");
            Callback cb = new Callback();
            IntPtr intptr_delegate = Marshal.GetFunctionPointerForDelegate(Callback.delegateCallback); //convert delegate to function pointer which can be used by unmanaged code
            Console.WriteLine("The callback return is 0", io.ManagedTakeCallback(intptr_delegate)); 
            Console.WriteLine("Please hit Enter to exit");
            String value = Console.In.ReadLine();
            //Console.WriteLine("End of program ", value);
        
    

和,

C++/CLI 互操作 dll h 和 cpp 文件:

//HEADER

namespace Interop


typedef double (__stdcall *PCallback)(double value1, double value2);

    public ref class InteropDLL
    
    public:
        double ManagedAdd(double value1, double value2);

    public:
        double ManagedTakeCallback(PCallback pCallback);
    ;


//CPP

double Interop::InteropDLL::ManagedAdd(double value1, double value2)

    return NativeAdd(value1, value2);


double Interop::InteropDLL::ManagedTakeCallback(PCallback pCallback)

    return NativeTakeCallback();

C++/CLI 互操作层然后调用 C DLL。我可以调用ManagedAdd 互操作函数;但是,如果添加了ManagedTakeCallback,则会出现 Windows 编译器错误。我怀疑 C# 应用程序没有通过 ManagedTakeCallback 函数正确地编组函数指针,或者 C++/CLI 端的签名不正确?如果有任何见解,我将不胜感激。

【问题讨论】:

错误信息到底是什么? 为什么不直接将委托传递给 C++/CLI? 哇,你从哪里得到这个 windows 编译器? :) 抱歉,忘记传递错误信息:Program.cs(36,61): error CS0570: 'ManagedTakeCallback' is not supported by the language 当需要本地函数指针时,您正在尝试传递 IntPtr。很不清楚您要做什么,但要让此代码在任何地方运行,您必须将 ManagedTakeCallback() 参数声明为 IntPtr 并使用 (PCallback)(void*)pCallback 强制转换为 PCallback。传递委托是更好的方法。 【参考方案1】:

以下是现场评论:

“但是C#不支持C++函数指针,所以我们不能在这里调用C++函数指针。C#只有Delegate对象,我们必须通过Marshal.GetDelegateForFunctionPointer将函数指针转换为Delegate。它是在System中声明的。 Runtime.InteropServices 如下:

公共静态委托 GetDelegateForFunctionPointer ( IntPtr 指针, 类型 t)

完整答案请查看链接: http://www.codeproject.com/Articles/27298/Dynamic-Invoke-C-DLL-function-in-C

【讨论】:

以上是关于将 C# 函数指针传递到 C++/CLI 互操作 dll的主要内容,如果未能解决你的问题,请参考以下文章

关于通过 ref、空指针和 IntPtr 传递结构的互操作问题

本机 C++ 程序在使用 C++/CLI 和 C# 互操作 DLL 启动时崩溃

将 C++/CLI 类方法作为 C 函数指针传递

将 C# 与 C 函数互操作的性能损失 [关闭]

通过互操作将字符串数组从 C# 传递到 C++

使用 COM 互操作将对象从 C# 传递到 VBA