C++插件管理类(下)——实际项目(阉割版)

一、背景

请参考C++插件管理类(上)

二、代码结构

在这里插入图片描述

三、两个CMakeLists.txt

3.1 父目录

#设置cmake的最低版本
cmake_minimum_required(VERSION 3.10)
# Set CMAKE_SKIP_BUILD_RPATH to TRUE
# 设置工程的名称
project(PluginManagers)

# 设置库和可执行文件的输出目录
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

add_subdirectory(src)
# 将源代码添加到工程生成可执行文件
add_executable(PluginManagers main.cpp Plugin.h Plugin.cpp Comm.h)

3.2 子目录src

cmake_minimum_required(VERSION 3.0)
message("${CMAKE_BINARY_DIR}/${IDE_BIN_DIR}")
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/${IDE_BIN_DIR})
add_library(calcu SHARED "calcu.cpp")

四、代码实例

4.1 main.cpp

#include<iostream>
#include <vector>
#include "Plugin.h"
#include "Comm.h"
using namespace std;
typedef int (*_add_function_)(int a, int b);
typedef int (*_sub_function_)(int a, int b);
int main()
{
	PluginMannager plug;
	if (FAILURE == plug.tuiLoadPlugin("calcu"))
	{
		cout << "Has No DLL" << endl;
	}
	void* func = nullptr;
	if (FAILURE == plug.getFunction(func, ADD_FUNCTION))
	{
		return false;
	}
	int Sum=((_add_function_)func)(1,2);
	cout << "Sum is:" << Sum << endl;

	if (FAILURE == plug.getFunction(func, SUB_FUNCTION))
	{
		return false;
	}
	int Sub= ((_sub_function_)func)(1, 2);
	cout << "Sub is:" << Sub << endl;
	return 0;
}

4.2 Plugin.h

#include<iostream>
#include <vector>
using namespace std;
typedef void* PluginHandle;
typedef struct PluginInterfaceInformatin
{
	string dllName = "";
	string version = "";
	string interfaceName = "";
	PluginHandle function = NULL;
	int type = -1;

}PluginInfo;

using PluginInfoVector = std::vector<PluginInfo>;

class Plugin
{
public:
	bool Init(const std::string& filename);
	bool Execute(void* &func, int type);
private:
	PluginHandle handle = nullptr;
	PluginInfoVector EntryVector;
};

class PluginMannager
{
public:
	/*加载插件*/
	bool tuiLoadPlugin(const std::string& filename);
	/*获取函数指针*/
	bool getFunction(void*& func, int type);
private:
	/*插件库*/
	std::vector<Plugin> pluginList;
};

4.3 Plugin.cpp

#include "Plugin.h"
#include "Comm.h"
#include <Windows.h>

bool Plugin::Init(const std::string& filename)
{
	PluginHandle handle = nullptr;
	handle = LoadLibrary(filename.c_str());
	if (handle == nullptr)
		return FAILURE;
	this->handle = handle;
	this->EntryVector.swap(*(PluginInfoVector*)GetProcAddress((HMODULE)handle, str(plugins)));
	return SUCCESS;
}

bool Plugin::Execute(void* &func, int type)
{
	for (auto& entry : this->EntryVector)
	{
		if(type == entry.type)
		{
			func = entry.function;
			return SUCCESS;
		}
	}
	return 0;
}

bool PluginMannager::tuiLoadPlugin(const std::string& filename)
{
	Plugin plug;
	if (FAILURE == plug.Init(filename))
	{
		return FAILURE;
	}
	this->pluginList.push_back(plug);
	return SUCCESS;
}

bool PluginMannager::getFunction(void*& func, int type)
{
	for (auto& plug : pluginList)
	{
		if (SUCCESS == plug.Execute(func, type))
		{
			return SUCCESS;
		}
		else
		{
			return FAILURE;
		}
	}
	return SUCCESS;
}

4.4 Comm.h

#if (_WIN32) || (_WIN64)
#define PLUGIN_EXPORT extern "C" _declspec(dllexport) 
#else
#define PLUGIN_EXPORT exter "C" 
#endif

typedef enum PLUGIN_FUN_TYPE
{
	ADD_FUNCTION = 0,
	SUB_FUNCTION
};

#define __data__ plugins

#define PLUGIN_DATA(...) PluginInfoVector __data__={__VA_ARGS__}

#define PLUGIN_DEFINE					 \
PLUGIN_EXPORT PluginInfoVector	__data__ ;\

#define str(e) #e

#define SUCCESS 0
#define FAILURE 1

4.5 calc.cpp

#include "../Plugin.h"
#include "../Comm.h"
PLUGIN_DEFINE

int add(int x, int y)
{
	return x + y;
}
int sub(int x, int y)
{
	return x - y;
}

PLUGIN_DATA({ "calc", "1.0","add",(void*)add, ADD_FUNCTION }
,{ "calc", "1.0","sub",(void*)sub, SUB_FUNCTION });

五、 踩坑点

🎈:可执行文件和库文件需要再同一文件目录下:所以需要使用CMake宏去限定生成目录
在这里插入图片描述

七、 项目地址

地址

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
代号为X3的C++轻量级通用插件框架平台是一套通用的C++轻量级插件体系,由多个独立插件模块组成。应用程序可以基于X3插件框架进行快速开发,X3插件框架中的插件既可以单独使用,又可以灵活组合使用。X3插件框架采用VC++开发,没有使用MFC、ATL、COM,已经过3年十几个系统的实际使用验证。 目前X3插件框架包括插件内核部分(插件基础、插件管理器、Observer管理插件、日志管理插件)和实用技术插件(XML读写封装插件、数据库操作封装插件、文件操作实用插件、文本操作实用插件、本地化字符串表插件等)。 X3插件框架的特点有: a) 接口定义简单灵活 采用普通的C++接口,即由纯虚函数组成的结构体,不需要特殊的基,不需要宏和UUID申明;同时可以使用C++的各种变量型,不受COM接口那样的约束。例如下面的接口Ix_定义: interface Ix_Example { virtual void Foo() = 0; virtual void* GetData(std::vector& items) = 0; }; b) 接口与实现分离 对外提供接口文件,在插件内部用来实现一个或多个接口,不需要对外导出该或暴露实现细节。这样还有一个好处是只有约定了接口就可以让多个模块并行开发,模块相互之间不存在编译依赖(不需要其他插件的LIB等文件),这可用于测试驱动开发模式。 c) 多接口转换、引用计数管理 采用智能指针管理接口的引用计数及生命期,可从一个接口动态转换为另一个接口(内部采用C++的RTTI机制动态转换),可以区分插件内部的接口引用和插件外部的接口引用。 d) 模块透明部署 一个模块只需要使用其他模块的接口,不需要关心该接口是在哪个插件中实现的。可以根据需要将各个实现进行合并或拆分,使其分布到不同插件中,而接口使用者不受影响。另外,插件部署于哪个目录也不影响插件接口的使用。 e) 模块可替换、可扩展 可根据需要替换某个插件,只有该插件实现了相同的接口,即使内部功能不相同,这样就实现了插件可替换、按需组合。通过在新的插件中支持更多的接口,可扩展更多的功能。可以在新插件中局部替换原有插件的某些接口或部分函数,实现重用和扩展。 f) 线程安全性 本插件机制所提供的内部实现文件考虑了线程安全性,允许多线程访问而不冲突,同时采用的是轻量级的锁定机制(计数原子锁定),运行开销很小。 g) 跨本 允许不同本的VC++开发的插件相互调用对方的接口,虽然实际中一般不需要这样做。由于没有采用VC++特殊的编译指令,因此容易移植到其他开发平台下。 编译运行环境 本插件机制采用C++实现,用到了C++的RTTI机制和少量Windows API函数,没有使用MFC、ATL、STL,没有使用LIB文件,外部依赖文件少,没有使用VC++特殊编译指令。 编译环境为Visual C++ 6.0/2003/2005/2008/2010,其他C++开发平台下待测试(从实现原理上看应该没问题)。 运行环境为Windows 2000及以后的操作系统,Windows 98需要安装UNICODE支持包。 X3插件框架目前在局部范围内开放源码,还未在公共开源网站范围正式开放。可以学习研究、任意修改改进,但不可以换成其他作者另外发布,转载时请列出来源。 有改进意见可在博客地址或者邮件中提出。 博客:http://www.cnblogs.com/rhcad 邮件:rhcad@hotmail.com 详细描述见 http://www.cnblogs.com/rhcad/archive/2010/09/27/1836943.html 附件内容: .\Product_vc100.sln .\Product_vc60.dsw .\Product_vc80.sln .\Product_vc90.sln .\Code ------\pkg_Core ------\pkg_Example ------\pkg_UnitTest ------\pkg_Core\Interface ------\pkg_Core\Modules ------\pkg_Core\Interface\AppUI ------\pkg_Core\Interface\ChangeObserver ------\pkg_Core\Interface\Ix_Object.h ------\pkg_Core\Interface\Ix_ObjectFactory.h ------\pkg_Core\Interface\Log ------\pkg_Core\Interface\Module ------\pkg_Core\Interface\PluginManager ------\pkg_Core\Interface\UtilFunc ------\pkg_Core\Interface\Utility ------\pkg_Core\Interface\XComPtr.h ------\pkg_Core\Interface\Xml ------\pkg_Core\Interface\AppUI\CmdMsgObserverSimple.h ------\pkg_Core\Interface\AppUI\Cx_CreateWnd.h ------\pkg_Core\Interface\AppUI\Ix_CreateWnd.h ------\pkg_Core\Interface\AppUI\RawCmdMsgObserver.h ------\pkg_Core\Interface\ChangeObserver\ChangeNotifyData.h ------\pkg_Core\Interface\ChangeObserver\Ix_ChangeManager.h ------\pkg_Core\Interface\ChangeObserver\Ix_ChangeObserver.h ------\pkg_Core\Interface\Log\DebugR.cpp ------\pkg_Core\Interface\Log\DebugR.h ------\pkg_Core\Interface\Log\ILogObserver.h ------\pkg_Core\Interface\Log\Ix_LogManager.h ------\pkg_Core\Interface\Log\LogHelper.h ------\pkg_Core\Interface\Module\Cx_Module.h ------\pkg_Core\Interface\Module\Cx_Object.h ------\pkg_Core\Interface\Module\Cx_SimpleObject.h ------\pkg_Core\Interface\Module\Cx_SingletonObject.h ------\pkg_Core\Interface\Module\Ix_Module.h ------\pkg_Core\Interface\Module\XClassItem.h ------\pkg_Core\Interface\Module\XModuleImpl.h ------\pkg_Core\Interface\Module\XModuleItem.h ------\pkg_Core\Interface\Module\XModuleMacro.h ------\pkg_Core\Interface\PluginManager\Ix_PluginLoader.h ------\pkg_Core\Interface\PluginManager\PluginManager.h ------\pkg_Core\Interface\PluginManager\XComCreator.h ------\pkg_Core\Interface\UtilFunc\AutoNew.h ------\pkg_Core\Interface\UtilFunc\ConvStr.h ------\pkg_Core\Interface\UtilFunc\ctrim.h ------\pkg_Core\Interface\UtilFunc\func_s.h ------\pkg_Core\Interface\UtilFunc\LockCount.h ------\pkg_Core\Interface\UtilFunc\LockSyn.h ------\pkg_Core\Interface\UtilFunc\ReadInts.h ------\pkg_Core\Interface\UtilFunc\RelToAbs.h ------\pkg_Core\Interface\UtilFunc\RoundStr.h ------\pkg_Core\Interface\UtilFunc\SafeCall.h ------\pkg_Core\Interface\UtilFunc\ScanFiles.h ------\pkg_Core\Interface\UtilFunc\SysErrStr.h ------\pkg_Core\Interface\UtilFunc\vecfunc.h ------\pkg_Core\Interface\UtilFunc\vecptr.h ------\pkg_Core\Interface\Utility\ClsID_TextUtil.h ------\pkg_Core\Interface\Utility\Ix_ClipboardUtil.h ------\pkg_Core\Interface\Utility\Ix_ConfigDBFactory.h ------\pkg_Core\Interface\Utility\Ix_FileTransaction.h ------\pkg_Core\Interface\Utility\Ix_FileUtility.h ------\pkg_Core\Interface\Utility\Ix_FileVersion.h ------\pkg_Core\Interface\Utility\Ix_GuidGenerator.h ------\pkg_Core\Interface\Utility\Ix_StringConvert.h ------\pkg_Core\Interface\Utility\Ix_TempFolder.h ------\pkg_Core\Interface\Utility\Ix_TextFileUtil.h ------\pkg_Core\Interface\Xml\ConfigIOSection.h ------\pkg_Core\Interface\Xml\IFileCryptHandler.h ------\pkg_Core\Interface\Xml\Ix_ConfigData.h ------\pkg_Core\Interface\Xml\Ix_ConfigSection.h ------\pkg_Core\Interface\Xml\Ix_ConfigSectionXml.h ------\pkg_Core\Interface\Xml\Ix_ConfigTransaction.h ------\pkg_Core\Interface\Xml\Ix_ConfigXml.h ------\pkg_Core\Interface\Xml\Ix_StringTable.h ------\pkg_Core\Interface\Xml\Ix_UIConfig.h ------\pkg_Core\Modules\ChangeManager\... ------\pkg_Core\Modules\LogManager\... ------\pkg_Core\Modules\PluginManager\... ------\pkg_Core\Modules\StringTable\... ------\pkg_Example\... ------\pkg_UnitTest\Interface\cppunit ------\pkg_UnitTest\Modules\TestCore ... .\Doc .\Doc\插件开发帮助.chm .\Doc\插件基础使用说明书.pdf
C++ 模板在实际项目中的应用非常广泛,特别是在涉及到多种数据型的算法和数据结构中。下面是一些实际项目中使用模板的例子: 1. STL 容器和算法:STL(标准模板库)是 C++ 中非常重要的一个库,其中包含了各种容器和算法。STL 中的容器和算法都是使用模板实现的,这使得 STL 可以适用于各种数据型,提高了代码的可重用性和扩展性。 2. 数据库访问:在数据库访问中,我们经常需要对不同型的数据进行操作。使用模板可以方便地实现对多种数据型的支持,同时也可以提高代码的可读性和可维护性。 3. 数值计算库:在数值计算中,我们需要对不同型的数据进行运算,例如矩阵乘法、向量加法等。使用模板可以方便地实现对多种数据型的支持,同时也可以提高代码的可读性和可维护性。 4. 图形库:在图形库中,我们需要对不同型的图形进行操作,例如画线、画矩形等。使用模板可以方便地实现对多种图形型的支持,同时也可以提高代码的可读性和可维护性。 总之,模板是 C++ 中非常重要的一个特性,它可以方便地实现对多种数据型的支持,提高代码的可重用性和扩展性,同时也可以提高代码的可读性和可维护性。在实际项目中,我们经常会使用模板来实现各种算法、数据结构、库等功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愿天堂没有C++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值