2020年6月10日 星期三

Template cxxlObjectPlugin 插件

這是個範例,用來示範如何把 template class 做成 cxxlObjectPlugin 插件,下載點:
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.cpp
 1 #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  }



沒有留言:

張貼留言