Template cxxlObjectPlugin.7z
因範例是用 Console 視窗顯示 utf-8 文字,所以先參考 修改 Win10 的 Console 視窗顯示 UTF-8
因 cxxlObjectPlugin 插件須在執行時期經由 CM 在 .cpp 程式中建立,而 template class 則是在編譯時期就須產生物件,解決的辦法是把產生 template class 物件的程式碼帶到 .cpp 中執行。見 Plugin.HPP 中 IPlugin1<T>::Create() 的做法,而在 Plugin.cpp 中 IPlugin1_New() 負責執行以產生 IPlugin1<T> 物件。
一般來說 cxxlObjectPlugin 插件會做成 介面類別 <-- 實作類別 的繼承架構,IPlugin2<T> 就試圖這樣搞,但實作類別會在 .cpp 中,編譯完後早就寫死了,如何去繼承 template 介面類別, IPlugin2<T>::Create() 就試圖這樣搞,但沒成功。
Plugin.HPP 檔1 /*------------------------------------------------------------------------ 2 3 Plugin.HPP v1.0.0 4 5 Copyright 楊志賢 CxxlMan, 2020 6 All Rights Reserved 7 8 ------------------------------------------------------------------------*/ 9 #if !defined(__Plugin_HPP_TEST) 10 #define __Plugin_HPP_TEST 11 12 #include <sstream> 13 #include <CM.HPP> 14 #include <CXXLML.HPP> 15 16 #define GROUP "TestGroup" 17 18 // 插件介面的識別碼 19 #define IPluginLang_InterfaceID u8"6B6C080E31EF4D3D9254C4EB7F6434D3" 20 #define IPlugin1_InterfaceID u8"4BD1A7984FB34CC796084E5C24E7CF34" 21 #define IPlugin2_InterfaceID u8"393D184752C8424D958A4017E7619362" 22 23 namespace TEST 24 { 25 26 class IPluginLang :virtual public CxxlMan2::cxxlObjectPlugin 27 { 28 virtual void cxxlFASTCALL SetLang(const CxxlMan2::UTF8_String &Lang) const = 0; 29 virtual void cxxlFASTCALL Show(const CxxlMan2::UTF8_String &Type, 30 const CxxlMan2::UTF8_String &Value) const = 0; 31 public: 32 33 // 設定插件的顯示,採用哪種語言 34 static void cxxlFASTCALL Set(const CxxlMan2::UTF8_String &Lang) 35 { 36 auto IPluginLang_Ptr = CxxlMan2::Smart_Cast<IPluginLang>( 37 CxxlMan2::cxxlCM_GetElement(IPluginLang_InterfaceID, GROUP)); 38 IPluginLang_Ptr->SetLang(Lang); 39 } 40 41 static void cxxlFASTCALL Show_IPlugin1_m_Var(const CxxlMan2::UTF8_String &Type, 42 const CxxlMan2::UTF8_String &Value) 43 { 44 auto IPluginLang_Ptr = CxxlMan2::Smart_Cast<IPluginLang>( 45 CxxlMan2::cxxlCM_GetElement(IPluginLang_InterfaceID, GROUP)); 46 IPluginLang_Ptr->Show(Type, Value); 47 } 48 }; 49 50 template <typename T> 51 class IPlugin1:virtual public CxxlMan2::cxxlObjectPlugin 52 { 53 T m_Var; 54 public: 55 56 void cxxlFASTCALL SetVar(T Var) 57 { 58 m_Var = Var; 59 } 60 61 virtual void cxxlFASTCALL Show() const 62 { 63 std::stringstream s; 64 s << m_Var; 65 IPluginLang::Show_IPlugin1_m_Var(typeid(m_Var).name(), s.str()); 66 } 67 68 static CxxlMan2::Smart_Ptr<IPlugin1<T> > cxxlFASTCALL Create() 69 { 70 // 為了能經由 CM 產生 cxxlObjectPlugin 71 // 無延伸類別的做法 72 auto Arg = std::function<cxxlObjectPlugin*()>([]() 73 { 74 return new IPlugin1<T>; 75 }); 76 77 return CxxlMan2::Smart_Cast<IPlugin1<T> >( 78 CxxlMan2::cxxlCM_GetElement(IPlugin1_InterfaceID, GROUP, (void*)&Arg) 79 ); 80 } 81 }; 82 83 // 在 Plugin.cpp 實作 84 // pType 不會被用到,只是藉由它取得 IPlugin2 的 type 85 template <typename T> 86 CxxlMan2::cxxlObjectPlugin* cxxlFASTCALL IPlugin2_Create(T *pType); 87 88 template <typename T> 89 class IPlugin2 :virtual public CxxlMan2::cxxlObjectPlugin 90 { 91 T m_Var; 92 protected: 93 T cxxlFASTCALL GetVar() const 94 { 95 return m_Var; 96 } 97 public: 98 99 void cxxlFASTCALL SetVar(T Var) 100 { 101 m_Var = Var; 102 } 103 104 virtual void cxxlFASTCALL Show() const = 0; 105 106 static CxxlMan2::Smart_Ptr<IPlugin2<T> > cxxlFASTCALL Create() 107 { 108 // 為了能經由 CM 產生 cxxlObjectPlugin 109 // 有延伸類別的做法 110 auto Arg = std::function<cxxlObjectPlugin*()>([]() 111 { 112 return ::IPlugin2_Create<IPlugin2>((IPlugin2*)nullptr); 113 }); 114 115 return CxxlMan2::Smart_Cast<IPlugin2<T> >( 116 CxxlMan2::cxxlCM_GetElement(IPlugin1_InterfaceID, GROUP, (void*)&Arg) 117 ); 118 } 119 }; 120 121 } /* namespace TEST */ 122 #endif 123
Plugin.cpp1 #include <iostream> 2 #include <Plugin.HPP> 3 4 using namespace std; 5 using namespace CxxlMan2; 6 using namespace TEST; 7 8 class CPluginLang :public IPluginLang 9 { 10 virtual void cxxlFASTCALL SetLang( 11 const CxxlMan2::UTF8_String &Lang) const override // class IPluginLang 12 { 13 cxxlML_SetLang(Lang); 14 } 15 16 virtual void cxxlFASTCALL Show(const CxxlMan2::UTF8_String &Type, 17 const CxxlMan2::UTF8_String &Value) const override // class IPluginLang 18 { 19 cout << CxxlMan2::ML(u8"The type of m_Var: ").c_str() << Type.c_str() << endl 20 << CxxlMan2::ML(u8"The value of m_Var: ").c_str() << Value.c_str() << endl; 21 } 22 23 public: 24 }; 25 26 27 template <typename BASE> 28 class CPlugin2 :public BASE 29 { 30 virtual void cxxlFASTCALL Show() const override 31 { 32 auto Var = BASE::GetVar() 33 34 cout << ML(u8"The type of Var: ").c_str() << typeid(m_Var).name() << endl 35 << ML(u8"The value of Var: ").c_str() << m_Var << endl; 36 } 37 38 public: 39 40 }; 41 42 43 template <typename T> 44 cxxlObjectPlugin* cxxlFASTCALL TEST::IPlugin2_Create(T *pType) 45 { 46 return new CPlugin2<T>; 47 } 48 49 50 // 定義在 dllmain.cpp 51 extern void cxxlFASTCALL Reg_FuncNew( 52 cxxlObjectPlugin *(cxxlFASTCALL *pFuncNew)(void *Arg), 53 const UTF8_String &InterfaceID); 54 extern void cxxlFASTCALL Reg_FuncRegenerateNew( 55 Regenerate *(cxxlFASTCALL*pFuncRegenerateNew)(), 56 const UTF8_String &ImplementingID); 57 58 cxxlObjectPlugin *cxxlFASTCALL IPluginLang_New(void *Arg) 59 { 60 return new CPluginLang; 61 } 62 63 cxxlObjectPlugin *cxxlFASTCALL IPlugin1_New(void *Arg) 64 { 65 return (*(std::function<cxxlObjectPlugin*()>*)Arg)(); 66 } 67 68 cxxlObjectPlugin *cxxlFASTCALL IPlugin2_New(void *Arg) 69 { 70 return (*(std::function<cxxlObjectPlugin*()>*)Arg)(); 71 } 72 73 // 提供給 dllmain.cpp 呼叫 74 void cxxlFASTCALL OpenGLRcMgr_Reg() 75 { 76 Reg_FuncNew(IPluginLang_New, IPluginLang_InterfaceID); 77 Reg_FuncNew(IPlugin1_New, IPlugin1_InterfaceID); 78 Reg_FuncNew(IPlugin2_New, IPlugin2_InterfaceID); 79 }
沒有留言:
張貼留言