【发布时间】: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。传递委托是更好的方法。