DynamicLinkLibraryAPI

来源:互联网 发布:大数据需求分析 编辑:程序博客网 时间:2024/06/06 02:47

DynamicLinkLibraryAPI.h


尝试使用,动态链接库技术,来实现脚本刷新。


#pragma once#if defined(WIN32) || defined(WIN64)#include <Windows.h>typedef HINSTANCE DLLHANDLER;#elif defined(__linux__)#include <dlfcn.h>typedef void* DLLHANDLER;#endifnamespace dll {// 打开动态链接库。bool OpenDLL(DLLHANDLER* pDLLHander, const char* path#if defined(__linux__), int mode = RTLD_NOW#endif);// 通过名称获得动态链接库中的函数或变量地址。void* GetDLL(DLLHANDLER* pDLLHander, const char* name);// 关闭动态链接库bool CloseDLL(DLLHANDLER* pDLLHander);}

DynamicLinkLibraryAPI.cpp

#include "DynamicLinkLibraryAPI.h"#include <stdio.h>namespace dll {bool OpenDLL(DLLHANDLER* pDLLHander, const char* path#if defined(__linux__), int mode#endif) {if (!pDLLHander || !path) {#ifndef NDEBUGprintf("\n=====================================================\n");printf("\tDEBUG:\n%s[%d]%s\t", __FILE__, __LINE__, "openDLL fial: null args");printf("\n=====================================================\n");#endifreturn false;}#if defined(WIN32) || defined(WIN64)*pDLLHander = LoadLibrary(path);#elif defined(__linux__)*pDLLHander = dlopen(path, mode);#endif#ifndef NDEBUG#if defined(WIN32) || defined(WIN64)printf("\n=====================================================\n");printf("\tDEBUG:\n%s[%d]path=[%s]\t", __FILE__, __LINE__, path);printf("\n=====================================================\n");#elif defined(__linux__)printf("\n=====================================================\n");printf("\tDEBUG:\n%s[%d]path=[%s] mode=[%d]\t", __FILE__, __LINE__, path, mode);printf("\n=====================================================\n");#endif#endifreturn pDLLHander != nullptr;}void* GetDLL(DLLHANDLER* pDLLHander, const char* name) {if (!pDLLHander || !name) {#ifndef NDEBUG    printf("\n=====================================================\n");    printf("\tDEBUG:\n%s[%d]%s\t", __FILE__, __LINE__, "getDLL fial: null args");    printf("\n=====================================================\n");#endifreturn nullptr;}#if defined(WIN32) || defined(WIN64)return GetProcAddress(*pDLLHander, name);#elif defined(__linux__)return dlsym(*pDLLHander, name);#endif}bool CloseDLL(DLLHANDLER* pDLLHander) {bool flag = false;if (pDLLHander) {#if defined(WIN32) || defined(WIN64)flag = FreeLibrary(*pDLLHander);#elif defined(__linux__)flag = (dlclose(*pDLLHander) == 0);#endif}#ifndef NDEBUGif (flag) {printf("\n=====================================================\n");printf("\tDEBUG:\n%s[%d] %s\t", __FILE__, __LINE__, "closeDLL succ");printf("\n=====================================================\n");} else {printf("\n=====================================================\n");printf("\tDEBUG:\n%s[%d] %s\t", __FILE__, __LINE__, "closeDLL fail");printf("\n=====================================================\n");}#endifreturn flag;}}

DynamicLinkLibraryMgr.h

#pragma once#include "DynamicLinkLibraryAPI.h"#include <ostream>#include <set>#include <map>#include <ctime>#include <string.h>#include <iostream>// 创建已知类型的脚本函数类,及对象。#define SCRIPTCLASS(NAME, DEFFUN)\class C##NAME {\protected:\typedef DEFFUN;\\static C##NAME* m_Instance;\\C##NAME() {\m_pScripts = new std::set<DEF>;\}\public:\\bool operator==(const C##NAME& ref) {\return m_Version == ref.m_Version;\}\\static C##NAME* Instance() {\if (!m_Instance) {\m_Instance = new C##NAME;\}\return m_Instance;\}\\const double GetVersion() const {\return m_Version;\}\\void SetVersion(double version) {\m_Version = version;\}\\const time_t GerCtime() const {\return m_Ctime;\}\\bool Reg(DLLHANDLER* dllHandler, const char* name) {\void* p = dll::GetDLL(dllHandler, name);\if (!p) {\std::cout << "can not find " << name << " dll fun" << std::endl;\return false;\}\if (p) {\m_pScripts->insert((DEF)p);\}\return true;\}\\std::set<DEF>* GetScripts() {\return this->m_pScripts;\}\\void Clear() {\this->m_pScripts->clear();\}\private:\doublem_Version;\time_tm_Ctime;\std::set<DEF>* m_pScripts;\};\C##NAME* C##NAME::m_Instance = nullptr;\// 动态函数class CDynamicLinkFun {// 类中声明friend std::ostream& operator<<(std::ostream& os, const CDynamicLinkFun& ref);public:CDynamicLinkFun(const char* name, const char* tname, void* fun) ;private:char m_Name[64];char m_Tname[128];void* m_Fun;time_t m_Ctime;};class CDynamicLinkLibrary {public:CDynamicLinkLibrary(const char* name, const char* path) ;~CDynamicLinkLibrary() ;// 获得动态库地址const char* GetPath() const ;// 设置动态库地址void SetPath(const char* path) ;// 初始化bool Init() ;// 销毁bool Destory() ;// 重新加载bool Reload() ;private:// 库名称charm_Name[64];// 库地址charm_Path[128];// 加载时间time_tm_Ctime;// 该动态库中的所有函数std::map<const char*, CDynamicLinkFun*>m_Scripts;// 动态链接库描述DLLHANDLER*m_pDLLHander;// 状态:0为默认,1为已初始化intm_State;};class CDynamicLinkLibraryMgr {public:// 重新加载所有int reloadDLLs();};


DynamicLinkLibraryMgr.cpp

#include "DynamicLinkLibraryMgr.h"// 类外定义std::ostream& operator<<(std::ostream& os, const CDynamicLinkFun& ref) {os << " Name:" << ref.m_Name << " TName:" << ref.m_Tname << " Address:" << std::showpoint << ref.m_Fun;return os;}CDynamicLinkFun::CDynamicLinkFun(const char* name, const char* tname, void* fun) {strcpy(m_Name, name);strcpy(m_Tname, tname);m_Fun = fun;time(&m_Ctime);}CDynamicLinkLibrary::CDynamicLinkLibrary(const char* name, const char* path) {m_State = 0;m_pDLLHander = new DLLHANDLER;strcpy(m_Name, name);strcpy(m_Path, path);time(&m_Ctime);} CDynamicLinkLibrary::~CDynamicLinkLibrary() {Destory();m_pDLLHander = nullptr;}const char* CDynamicLinkLibrary::GetPath() const {return this->m_Path;}void CDynamicLinkLibrary::SetPath(const char* path) {strcpy(m_Path, path);}bool CDynamicLinkLibrary::Init() {if (m_State) {#ifndef NDEBUGprintf("\n=====================================================\n");printf("\tDEBUG:\n%s[%d] %s\t", __FILE__, __LINE__, "动态链接库已初始化,无法再初始化!");printf("\n=====================================================\n");#endifreturn false;}if (dll::OpenDLL(m_pDLLHander, m_Path)) {m_State = 1;// void GetScripts(std::map<const char*, const char*>& scripts)void (*GetScripts)(std::map<const char*, const char*>& scripts) = reinterpret_cast<void (*) (std::map<const char*, const char*>& scripts)>(dll::GetDLL(m_pDLLHander, "GetScripts"));if (!GetScripts) {return false;}std::map<const char*, const char*> __map;GetScripts(__map);for (auto kv : __map) {std::cout << kv.first << " " << kv.second << std::endl;#ifndef NDEBUGbool flag = true;#endifif (strlen(kv.first) > 0 && strlen(kv.second) > 0) {void* fun = dll::GetDLL(m_pDLLHander, kv.first);if (fun) {m_Scripts.insert(std::make_pair(kv.first, new CDynamicLinkFun(kv.first, kv.second, fun)));#ifndef NDEBUGflag = false;#endif}}#ifndef NDEBUGif (flag) {printf("\n=====================================================\n");printf("\tDEBUG:\n%s[%d]%s %s %s\t", __FILE__, __LINE__, "load function fail", kv.first, kv.second);printf("\n=====================================================\n");}#endif}std::cout << "\n---------------------------" << std::endl;#ifndef NDEBUGfor (auto kv : m_Scripts) {std::cout << *(kv.second) << std::endl;}#endifreturn true;}return false;}bool CDynamicLinkLibrary::Destory() {if (!m_State) {#ifndef NDEBUGprintf("\n=====================================================\n");printf("\tDEBUG:\n%s[%d] %s\t", __FILE__, __LINE__, "动态链接库尚未初始化,无法销毁!");printf("\n=====================================================\n");#endifreturn false;}bool rt = dll::CloseDLL(m_pDLLHander);if (rt) {m_State = 0;}for (auto kv : m_Scripts) {kv.second = nullptr;}m_Scripts.clear();return rt;}bool CDynamicLinkLibrary::Reload() {Destory();return Init();}

min.cpp

#include "DynamicLinkLibraryMgr.h"#include <iostream>#include <thread>#include <fstream>#include <string>#include <string.h>#if defined(WIN32) || defined(WIN64)#define path "../Debug/SayHello.dll"#elif defined(__linux__)#define path "../Debug/SayHello.so"#endifbool bReload = true;char path2[126] = {0};int test(DLLHANDLER* pHandler);int reload(DLLHANDLER* pHandler);// SCRIPTCLASS(LoginPreScript, void (*DEF) (void*) )int main(int argc, char **argv) {CDynamicLinkLibrary* pDynamicLinkLibrary = nullptr;if (argc == 2) {strcpy(path2, argv[1]);std::cout << "path2 " << path2 << std::endl;pDynamicLinkLibrary = new CDynamicLinkLibrary("test" ,path2);} else {pDynamicLinkLibrary = new CDynamicLinkLibrary("test", path);}pDynamicLinkLibrary->Init();return 0;}// // int main(int argc, char **argv) {// // if (argc == 2) {// strcpy(path2, argv[1]);// std::cout << "path2 " << path2 << std::endl;// }// // DLLHANDLER* pHandler = new DLLHANDLER;// std::thread t(// [&pHandler](){// // for (;;) {// test(pHandler);// }// }// );// t.detach();// // for (;;) {// // std::string str;// std::getline(std::cin, str);// strcpy(path2, str.c_str());// std::cout << "path2 " << path2 << std::endl;// reload(pHandler);// // // }// // return 0;// }// // int reload(DLLHANDLER* pHandler) {// bReload = true;// return dll::CloseDLL(pHandler);// }// // int test(DLLHANDLER* pHandler) {// // std::cout << "bReload :: " << std::boolalpha << bReload << std::endl;// std::cout << "path2 :: " << path2 << std::endl;// if (bReload) {// bReload = false;// // bool ret = false;// if (strlen(path2) > 0) {// ret = dll::OpenDLL(pHandler, path2);// } else {// ret = dll::OpenDLL(pHandler, path);// }// // if (!ret) {// std::cout << "can not open dll" << std::endl;// return -1;// }// // CLoginPreScript::Instance()->Clear();// CLoginPreScript::Instance()->Reg(pHandler, "loginPre1");// CLoginPreScript::Instance()->Reg(pHandler, "loginPre2");// // }// // auto scripts = CLoginPreScript::Instance()->GetScripts();// for (auto loginpre = scripts->begin(); loginpre != scripts->end(); loginpre++) {// (*loginpre)(nullptr);// }// // // // bool ret =  dll::closeDLL(pHandler);// // if (ret) {// // std::cout << "关闭成功" << std::endl;// // } else {// // std::cout << "关闭失败" << std::endl;// // }// // // // ret = dll::openDLL(pHandler, path);// // if (!ret) {// // std::cout << "打开动态链接库失败" << std::endl;// // return -1;// // }// // // // // // // // void* p = dll::getDLL(pHandler, "add");// // if (!p) {// // std::cout << "can not get dll method" << std::endl;// // return -2;// // }// // // // int (*addFun)(int, int) = (int(*)(int, int))p;// // int sum = addFun(1, 8);// // // // std::cout << "sum = " << sum << std::endl;// // // // // // void* p2 = dll::getDLL(pHandler, "add2");// // if (!p2) {// // std::cout << "can not get dll method" << std::endl;// // return -3;// // }// // // // int (*add2Fun)(int, int, int) = (int(*)(int, int, int))p2;// // int sum2 = add2Fun(1, 8, 10);// // // // std::cout << "sum2 = " << sum2 << std::endl;// // // // // // void* p3 = dll::getDLL(pHandler, "sayHello");// // if (!p3) {// // std::cout << "can not get dll method" << std::endl;// // return -4;// // }// // void (*sayHelloFun)() = (void(*)()) p3;// // // // sayHelloFun();// // // // void* (*getUser)() = (void* (*)()) dll::getDLL(pHandler, "getUser");// // // // void* pU = getUser();// // // // void (*printUser)(void*) = (void (*)(void*)) dll::getDLL(pHandler, "printUser");// // // // printUser(pU);// // // // #if defined(WIN32) || defined(WIN64)// // #elif defined(__linux__)// // char** name = (char**) dll::getDLL(pHandler, "name");// // int* age = (int*) dll::getDLL(pHandler, "age");// // std::cout << *name << std::endl;// // std::cout << *age << std::endl;// // // // #endif// // std::this_thread::sleep_for(std::chrono::seconds(10));// // return 1;// // }


以下是动态链接库项目:

DynamicLinkLibraryScript.cpp

#include <map>#ifndef DLL_API#if defined(WIN32) || defined(WIN64)#define DLL_API __declspec(dllexport)#elif defined(__linux__)#define DLL_API #endif#endifextern "C" DLL_API void GetScripts(std::map<const char*, const char*>& scripts) {scripts.insert(std::make_pair("loginPre1", "void (*loginPre1)(void*)"));scripts.insert(std::make_pair("loginPre2", "void (*loginPre2)(void*)"));scripts.insert(std::make_pair("add", "int (*add)(int ,int )"));scripts.insert(std::make_pair("add2", "int (*add2)(int , int , int )"));scripts.insert(std::make_pair("sayHello", "void (*sayHello)()"));scripts.insert(std::make_pair("getUser", "void* (*getUser)()"));scripts.insert(std::make_pair("printUser", "void (*printUser)(void*)"));}


LoginPreScript.cpp

#include <iostream>// void (*LoginPre) (void*)#ifndef DLL_API#if defined(WIN32) || defined(WIN64)#define DLL_API __declspec(dllexport)#elif defined(__linux__)#define DLL_API #endif#endifextern "C" DLL_API void loginPre1(void* p) {std::cout << "loginPre1 yyyyyy" << std::endl;}extern "C" DLL_API void loginPre2(void* p) {std::cout << "loginPre2 xxxxxx" << std::endl;}

Math.h

#pragma once#ifndef DLL_API#if defined(WIN32) || defined(WIN64)#define DLL_API __declspec(dllexport)#elif defined(__linux__)#define DLL_API #endif#endifextern "C" int DLL_API add(int x,int y);



Math.cpp

#include "Math.h"int add(int x,int y) {  return x + y;  }


Math2.cpp

#ifndef DLL_API#if defined(WIN32) || defined(WIN64)#define DLL_API __declspec(dllexport)#elif defined(__linux__)#define DLL_API #endif#endifextern "C" int DLL_API add2(int i, int j, int k) {return i + j + k + 100000;}


SayHello2.cpp

#include <iostream>#include <string.h>#ifndef DLL_API#if defined(WIN32) || defined(WIN64)#define DLL_API __declspec(dllexport)#elif defined(__linux__)#define DLL_API #endif#endifchar* name = "jack";int age = 27;extern "C" DLL_API void sayHello() {std::cout << "hello 3!" << name << age << std::endl;}class User {// 类中声明friend std::ostream& operator<<(std::ostream& os, const User& ref);public:User(const char* username, const char* password) {strcpy(this->username, username);strcpy(this->password, password);}const char* getUsername() const {return this->username;}const char* getPassword() const {return this->password;}private:char username[64];char password[64];};// 类外定义std::ostream& operator<<(std::ostream& os, const User& ref) {os << ref.username << " " << ref.password;return os;}User* pU = new User("jack", "pswd");extern "C" DLL_API User* getUser() {return pU;}extern "C" DLL_API void printUser(User* u) {std::cout << *u << std::endl;}












0 0
原创粉丝点击