来自C+的回调+;到C#
我有一个C++的主题/观察者系统:来自C+的回调+;到C#,c#,c++,C#,C++,我有一个C++的主题/观察者系统: #include <vector> class IObserver { public: virtual void valueChanged(float pos) = 0; }; class Subject { public: static Subject *instance(); void subscribe(IObserver *observer); private: static Subject*
#include <vector>
class IObserver
{
public:
virtual void valueChanged(float pos) = 0;
};
class Subject
{
public:
static Subject *instance();
void subscribe(IObserver *observer);
private:
static Subject* m_instance;
std::vector<IObserver*> m_observers;
};
如何将C成员函数转换为C++函数指针,调用最后一个函数?
< P> C不能实现C++接口,这需要从C++中完成。您可以使用C++/CLI来创建一个Simm观测器,实现接口,也可以理解C++代表,或者可以使用C++标准来实现一个Simm观测器实现接口并调用函数指针;C#委托可以转换为函数指针
最后一种方法是C++代码使用一个完整的COM接口(IDL),其中C++可以实现,而不是一个最小的C++接口。
对于带有函数指针的新代码:
typedef void (*ValueChangedFunc)(float pos);
void SubscribeTovalueChanged(ValueChangedFunc func); // global but works on singleton
首先,在C++端指定调用约定。< /P>
typedef void (__stdcall *ValueChangedFunc)(float pos);
void __stdcall SubscribeToValueChanged(ValueChangedFunc func); // global but works on singleton
然后声明一个与函数指针typedef匹配的委托
[UnmanagedFunctionPointer(CallingConvention.Stdcall)]
delegate void ValueChangedFunc(float);
然后声明使用它的函数:
[DllImport(...)]
void SubscribeToValueChanged(ValueChangedFunc func);
请注意,本机代码中使用的函数指针对垃圾收集器不可见。只要函数指针被保存,就要保持委托的生存性。/< P> < P> C不能实现C++接口,这需要从C++ +< /P>中完成。
您可以使用C++/CLI来创建一个Simm观测器,实现接口,也可以理解C++代表,或者可以使用C++标准来实现一个Simm观测器实现接口并调用函数指针;C#委托可以转换为函数指针
最后一种方法是C++代码使用一个完整的COM接口(IDL),其中C++可以实现,而不是一个最小的C++接口。
对于带有函数指针的新代码:
typedef void (*ValueChangedFunc)(float pos);
void SubscribeTovalueChanged(ValueChangedFunc func); // global but works on singleton
首先,在C++端指定调用约定。< /P>
typedef void (__stdcall *ValueChangedFunc)(float pos);
void __stdcall SubscribeToValueChanged(ValueChangedFunc func); // global but works on singleton
然后声明一个与函数指针typedef匹配的委托
[UnmanagedFunctionPointer(CallingConvention.Stdcall)]
delegate void ValueChangedFunc(float);
然后声明使用它的函数:
[DllImport(...)]
void SubscribeToValueChanged(ValueChangedFunc func);
请注意,本机代码中使用的函数指针对垃圾收集器不可见。您有责任在函数指针存储期间保持代理活动。非常感谢Ben!关于将C#委托转换为函数指针。我该怎么做?@Andy:这会给我一个IntPtr。如何将其转换为void*并调用C函数:void subscribe(void*p)?@Andy:(1)不要。只需在p/invoke声明中使用
IntPtr
。(2) void*
不是函数指针类型。Marshal.GetFunctionPointerForDelegate
的妙处在于它不需要单例;JIT编译器生成包含对特定对象的引用的本机代码,并转发给该对象上的实例方法。(3) 更好的是,在p/invoke声明中编写一个委托类型。p/invoke将为您调用Marshal.GetFunctionPointerForDelegate
。非常感谢Ben!关于将C#委托转换为函数指针。我该怎么做?@Andy:这会给我一个IntPtr。如何将其转换为void*并调用C函数:void subscribe(void*p)?@Andy:(1)不要。只需在p/invoke声明中使用IntPtr
。(2) void*
不是函数指针类型。Marshal.GetFunctionPointerForDelegate
的妙处在于它不需要单例;JIT编译器生成包含对特定对象的引用的本机代码,并转发给该对象上的实例方法。(3) 更好的是,在p/invoke声明中编写一个委托类型。p/invoke将为您调用Marshal.GetFunctionPointerForDelegate
。