`
chenqi210
  • 浏览: 79184 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

c++ Delegate

    博客分类:
  • c++
 
阅读更多

#ifndef DUMMYCLASS_H
#define DUMMYCLASS_H

namespace delegate
{
	class DummyClass{};
}

#endif
 

#ifndef METHODSTORAGE_H
#define METHODSTORAGE_H

#include "DummyClass.h"

namespace delegate
{
	class MethodStorage
	{
	public:
		typedef DummyClass GenericClass;
		typedef void (GenericClass::*GenericMemberFunctionPtr)();
		typedef void (*GenericFunctionPtr)();

		MethodStorage()
			:m_obj(0),
			m_member_fnptr(0),
			m_fnptr(0)
		{
		
		}

		inline bool operator == (MethodStorage const& other) const{return this->equals(other);}
		inline bool operator != (MethodStorage const& other) const{return !this->equals(other);}

		inline bool equals(MethodStorage const& other) const
		{
			return m_obj == other.m_obj 
				&& m_member_fnptr == other.m_member_fnptr
				&& m_fnptr == other.m_fnptr;
		}

	//protected:
		GenericClass *m_obj;
		GenericMemberFunctionPtr m_member_fnptr;
		GenericFunctionPtr m_fnptr;
	};
};

#endif
 

#ifndef METHODWRAPPER_H
#define METHODWRAPPER_H

#include "MethodStorage.h"

namespace delegate
{
	///This "Signature" is not a complete function pointer
	///corresponding signature to void (*)(int) is void(int)
	///and void (SomeClassType::*)(int) is void(int) as well
	template<typename Signature>
	class MethodWrapper;

	template<>
	class MethodWrapper< void () >
	{
	public:
		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType const& obj,void (MemberFunctionClass::*ptr)(void) const)
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)() >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(void)const )
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)() >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(void))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)() >;
		}

		MethodWrapper(void (*ptr)(void))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this);
			m_method.m_fnptr = reinterpret_cast<MethodStorage::GenericFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeFunction< MethodWrapper , void (*)() >;
		}

		void operator()()
		{
			(this->*internal_call)(m_method.m_obj);
		}
	private:
		typedef void (MethodWrapper::*internal_call_type)(void*);
		MethodStorage m_method;

		internal_call_type internal_call;

		template<typename ClassType,typename FunctionPtrType>
		void executeMemberFunction(void* obj)
		{
			(reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))();
		}

		template<typename ClassType,typename FunctionPtrType>
		void executeFunction(void* obj)
		{
			(*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))();
		}
	};
	template<typename ReturnType> 
	class MethodWrapper< ReturnType () >
	{
	public:
		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType const& obj,ReturnType (MemberFunctionClass::*ptr)(void) const)
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , ReturnType (MemberFunctionClass::*)() >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(void)const )
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , ReturnType (MemberFunctionClass::*)() >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(void))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , ReturnType (MemberFunctionClass::*)() >;
		}

		MethodWrapper(ReturnType (*ptr)(void))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeFunction< MethodWrapper , ReturnType (*)() >;
		}

		ReturnType operator()()
		{
			return (this->*internal_call)(m_method.m_obj);
		}
	private:
		typedef void (MethodWrapper::*internal_call_type)(void);
		MethodStorage m_method;

		internal_call_type internal_call;

		template<typename ClassType,typename FunctionPtrType>
		ReturnType executeMemberFunction(void* obj)
		{
			return (reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))();
		}

		template<typename ClassType,typename FunctionPtrType>
		ReturnType executeFunction(void* obj)
		{
			return (*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))();
		}
	};
	template<typename ArgType0> 
	class MethodWrapper< void ( ArgType0 ) >
	{
	public:
		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType const& obj,void (MemberFunctionClass::*ptr)(ArgType0) const)
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(const_cast<ClassType*>(&obj));
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(ArgType0)const )
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType const& obj,void (MemberFunctionClass::*ptr)(ArgType0))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(const_cast<ClassType*>(&obj));
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(ArgType0))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		MethodWrapper(void (*ptr)(ArgType0))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this);
			m_method.m_fnptr = reinterpret_cast<MethodStorage::GenericFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeFunction< MethodWrapper , void (*)(ArgType0) >;
		}

		void operator()(ArgType0 arg0)
		{
			(this->*internal_call)(m_method.m_obj, arg0);
		}
	private:
		typedef void (MethodWrapper::*internal_call_type)(void*,ArgType0);
		MethodStorage m_method;

		internal_call_type internal_call;

		template<typename ClassType,typename FunctionPtrType>
		void executeMemberFunction(void* obj,ArgType0 arg0)
		{
			(reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))(arg0);
		}

		template<typename ClassType,typename FunctionPtrType>
		void executeFunction(void* obj,ArgType0 arg0)
		{
			(*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))(arg0);
		}
	};
	template<typename ReturnType,typename ArgType0> 
	class MethodWrapper< ReturnType ( ArgType0 ) >
	{
	public:
		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType const& obj,ReturnType (MemberFunctionClass::*ptr)(ArgType0) const)
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(ArgType0)const )
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(ArgType0))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		MethodWrapper(ReturnType (*ptr)(ArgType0))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeFunction< MethodWrapper , void (*)(ArgType0) >;
		}

		ReturnType operator()(ArgType0 arg0)
		{
			return (this->*internal_call)(m_method.m_obj,arg0);
		}
	private:
		typedef ReturnType (MethodWrapper::*internal_call_type)(void*,ArgType0);
		MethodStorage m_method;

		internal_call_type internal_call;

		template<typename ClassType,typename FunctionPtrType>
		ReturnType executeMemberFunction(void* obj,ArgType0 arg0)
		{
			return (reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))(arg0);
		}

		template<typename ClassType,typename FunctionPtrType>
		ReturnType executeFunction(void* obj,ArgType0 arg0)
		{
			return (*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))(arg0);
		}
	};
}

#endif
 

 

 

compiler:MinGW 4.5.2 / VC++2010

 

 

C#式的delegate的重点之一是省略掉类型信息.

http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx 写道
class delegate
{
public:
    delegate()
        : object_ptr(0)
        , stub_ptr(0)
    {}

    template <class T, void (T::*TMethod)(int)>
    static delegate from_method(T* object_ptr)
    {
        delegate d;
        d.object_ptr = object_ptr;
        d.stub_ptr = &method_stub<T, TMethod>; // #1

        return d;
    }

    void operator()(int a1) const
    {
        return (*stub_ptr)(object_ptr, a1);
    }

private:
    typedef void (*stub_type)(void* object_ptr, int);

    void* object_ptr;
    stub_type stub_ptr;

    template <class T, void (T::*TMethod)(int)>
    static void method_stub(void* object_ptr, int a1)
    {
        T* p = static_cast<T*>(object_ptr);
        return (p->*TMethod)(a1); // #2

    }
};
 

 非常巧妙地隐藏掉了类型信息。但是本人对虚继承的委托还没有好的解决方法,也理解不了虚继承的成员函数的hack:http://www.codeproject.com/KB/cpp/FastDelegate.aspx

 

1
2
分享到:
评论

相关推荐

    C++中实现委托(delegate)

    网上有很多关于C++ delegate机制的文章,但都讲的是函数指针的内容,上周就C++中实现C#的delegate机制的问题研究了好几天,查看了很多相关资料,才解决了问题,现将我写的C++ delegate测试程序贴出来,希望能帮到有...

    C++实现delegate

    用C++做项目的时候,尤其是写客户端的时候经常会有事件回调的设计,一般的方式是使用虚函数表,用一个虚基类包含...但这种方式和C++11的lamda不兼容,为了更方便的实现事件回调机制,使用delegate是很不错的一种方式。

    C++下实现委托的代码

    在C++编程中,"委托"(Delegate)的概念源自于其他一些编程语言,如C#或Java,但在C++标准库中并没有内置的委托机制。然而,通过一些编程技巧,我们可以模拟实现类似的功能。委托通常用于传递函数或者方法作为参数,...

    CLI/C++反射机制交互C#、C++

    5. **反射调用**:通过`Type.GetMethod`获取接口中对应的方法信息,然后使用`Delegate.CreateDelegate`创建一个委托,最后通过委托来执行实际的方法调用。 在实际应用中,效率是一个关键因素。由于反射在运行时动态...

    C#调用C++动态DLL

    2. **创建C#的委托类型**:在C#中,使用`delegate`关键字定义一个委托类型,其方法签名与C++函数一致。这相当于声明C#中的函数指针,用于指向DLL中的函数。 3. **使用DllImport属性**:在委托类型上使用`[DllImport...

    c++ 与c#的中文字符串传递演示demo

    public delegate void CallbackDelegate(string message); // 在C++中声明回调函数类型 typedef void (*CallbackType)(const char*); // 在C++的DLL中,接收并保存回调函数指针 void RegisterCallback...

    C#调用C++动态库,执行回调函数并传递结构体参数

    delegate void CallbackDelegate(ref SomeStruct structure); ``` 其中`SomeStruct`是C#中定义的结构体,需要与C++的结构体完全匹配。注意,由于跨语言调用,结构体成员的排列顺序、大小和对齐方式必须一致。 接...

    Simple-Delegate:C++11 实验使用可变模板创建一个简单的委托风格的类

    标题 "Simple-Delegate:C++11 实验使用可变模板创建一个简单的委托风格的类" 指涉的是一个利用 C++11 的新特性来实现委托(delegate)设计模式的示例。委托是一种强大的设计模式,它允许将行为或方法的调用委托给另...

    C#调用c++函数的dll文件,同时实现c++调用c#函数

    delegate void ManagedCallback(int arg); void CallManagedMethod(ManagedCallback^ callback, int arg); }; ``` 3. **C++调用托管方法**:在C++代码中,通过实例化`ManagedBridge`对象并调用其成员函数,就可以...

    C#调用C++动态库中自身定义的回调函数

    在.NET框架中,C#作为高级编程语言,可以与非托管代码如C++进行交互,以便利用C++的性能优势和特定功能。本主题将详细探讨如何在C#应用程序中调用C++动态链接库(DLL)中的函数,并且在这个过程中,C#能够注册和处理...

    C#在C++中注册回调函数

    public delegate void MyCallback(string message); ``` 然后,我们创建一个类并实现这个委托类型的方法: ```csharp public class CallbackClass { public void MyCallbackMethod(string message) { Console...

    C#调C++动态库Dll C++回调C#函数

    delegate void CallbackDelegate(int value); ``` 3. **C#实现回调函数:** - 在C#中实现回调函数,如: ```csharp public static void MyCallback(int value) { Console.WriteLine($"Callback received: {...

    在Unity3d中使用C++ DLL 之 回调 示例

    public delegate void UnityCallback(int data); ``` - 实现Unity中的回调函数: ```csharp void UnityCallbackHandler(int data) { // 处理回调数据 } ``` - 在Unity的启动或初始化阶段,注册回调函数: ...

    C# 调用c++ 源码

    在IT行业中,跨语言通信是常见的需求,尤其是在C#与C++之间。C#是一种现代、面向对象的编程语言,而C++则以其强大的性能和底层控制能力著称。本篇将详细介绍如何在C#中调用C++编译的DLL(动态链接库)源码,以便在C#...

    c++与c#互调的例子

    public delegate int AddNumbersDelegate(int num1, int num2); [DllImport("TestDll.dll")] public static extern int AddNumbers(int num1, int num2); ``` 2. **C++调用C#的方法和事件**:在C++/CLI中,可以创建...

    C#使用委托(delegate)实现在两个form之间传递数据的方法

    关于Delegate【代理、委托】是C#中一个非常重要的概念,向前可以推演到C++的指针,向后可以延续到匿名方法、lambda表达式。 现在我就从一个最简单最实用的一个小例子出发分析一下Delegate的使用。 现在有两个窗体...

    delegate.zip

    委托类似于C++中的函数指针,但更安全,因为它们是类型安全的。你可以声明自己的委托类型,定义它能调用的方法的签名。 2. **委托创建**: 创建委托实例时,需要指定一个与该委托类型兼容的方法。例如,在C#中,...

    Applied C++ 书籍光盘

    在这个压缩包中,我们可以找到多个有助于深入理解C++编程的元素,包括一个实现图像缩放功能的类,异常处理机制,以及可能涉及的框架和委托(Delegate)概念。 首先,让我们关注这个“图像缩放类”。在C++中,实现...

    C# 调用C++DLL(函数参数包含指针)

    public delegate void MyFunctionDelegate(ref int ptr); ``` 然后,我们把`MyFunctionDelegate`作为`[DllImport]`特性修饰的方法的返回类型: ```csharp [DllImport("YourDllName.dll", CallingConvention = ...

    C#Winform动态调用C++和C#的Dll

    本文将重点讲解如何在C#的Winform应用中动态调用C++和C#编写的DLL,并将DLL作为嵌入资源处理,避免因丢失DLL文件而引发的问题。 首先,我们需要理解DLL的工作原理。DLL文件包含可执行代码和数据,当一个应用程序...

Global site tag (gtag.js) - Google Analytics