C++简单插件机制实现
在我做的第一个页游项目中,服务器使用了插件的机制,但是当时的插件都是用C#写,而且如何实现的也不是很清楚。之后的几个页游项目都是自己一个人包揽服务器部分,所以一直没有写插件的需求。下一个页游项目服务器这边需要多人合作,因此我想把其他模块都独立的做成插件的模式,目前也是在探索阶段。通过网上资料查找以及自己的整理,实现了一个简单版本的插件机制。实现代码如下:
文件Object.hpp中实现了所有插件类的基类,所有插件都要继承该类。
1 #ifndef __OBJECT_HPP__ 2 #define __OBJECT_HPP__ 3 4 class Object 5 { 6 public: 7 Object() {} 8 virtual ~Object() {} 9 virtual int Dump() = 0; 10 }; 11 12 #endif //__OBJECT_HPP__
文件TestObject.hpp以及TestObject.cpp是插件的实现类。
1 #ifndef __TESTOBJECT_HPP__ 2 #define __TESTOBJECT_HPP__ 3 4 #include "Object.hpp" 5 6 class TestObject : public Object 7 { 8 public: 9 virtual int Dump(); 10 }; 11 12 #endif //__TESTOBJECT_HPP__
1 #include "TestObject.hpp" 2 #include <iostream> 3 4 extern "C" 5 { 6 void *Instance() 7 { 8 return new TestObject; 9 } 10 } 11 12 int TestObject::Dump() 13 { 14 std::cout << "class name:TestObject function name:Dump()" << std::endl; 15 return 0; 16 }
文件main.cpp中加载和使用了插件,如果更深入一点的话这里可以写一个插件管理的类,专门负责插件的注册、对象的生成等工作。目前只为了演示功能故未做进一步研究。
1 #include <dlfcn.h> 2 #include <iostream> 3 #include "Object.hpp" 4 5 typedef Object *Instance(); 6 7 int main() 8 { 9 void *handle = dlopen("./libto.so", RTLD_LAZY); 10 if(!handle) 11 { 12 std::cout << dlerror() << std::endl; 13 return 1; 14 } 15 16 Instance *GetInstance = (Instance *)dlsym(handle, "Instance"); 17 if(!GetInstance) 18 { 19 std::cout << "Error Instance function" << std::endl; 20 return 1; 21 } 22 23 Object *obj = GetInstance(); 24 if(0 != obj) 25 { 26 obj->Dump(); 27 } 28 29 delete obj; 30 dlclose(handle); 31 32 return 0; 33 }
最后是makefile文件。
1 SOURCE=TestObject.cpp 2 makeso:${SOURCE} 3 g++ -fPIC -shared $^ -o libto.so 4 5 main: 6 g++ -o main -ldl main.cpp 7 8 clean: 9 rm -rf main *.o *.so 10 11 all:makeso main
程序的编译方式很简单,只要make all就可以了。运行过程如下:
1 [kiven@localhost plugin]$ make all 2 g++ -fPIC -shared TestObject.cpp -o libto.so 3 g++ -o main -ldl main.cpp 4 [kiven@localhost plugin]$ ./main 5 class name:TestObject function name:Dump() 6 [kiven@localhost plugin]$
整个程序都很简单,其中Object.hpp main.cpp两个文件是主程序,即游戏服务器的框架中要实现的功能。TestObject.hpp、TestObject.cpp是插件的具体实现,可以理解为具体游戏模块的实现。这里实现的插件机制是个雏形,只能用来演示功能,具体要用到游戏服务器中时插件还需要访问到主程序中的类,对象以及方法等。
完美之道,不在于无可增加,而在于无可减少。