QT/C++插件式框架、利用智能指针管理内存空间的实现、动态加载动态库文件

QT、C++插件框架、主要原理还是 动态库的动态加载、 dlopen()函数、下面为动态加载拿到Plugininstance对应指针、void**pp=(void**)dlsym(handle,"Plugininstance");

功能:添加单个插件
参数:libName:添加名为libName的插件
返回:成功返回true,失败返回false
*/
bool PluginManager::loadPlugin(const QString&libName)
{
void*handle=dlopen(libName.toLocal8Bit().data(),RTLD_LAZY); //打开动态库
if(handle==nullptr){
LOG(ERROR)<<"open "<<libName.toLocal8Bit().data()<<" error!:"<<dlerror();
return false;
}
void**pp=(void**)dlsym(handle,"Plugininstance");
if(pp==nullptr||*pp==nullptr){
LOG(ERROR)<<"get "<<libName.toLocal8Bit().data()<<" Instance error!";
return false;
}
PluginCore*pluginCore=static_cast<PluginCore*>(*pp);
if(pluginCore==nullptr){
LOG(ERROR)<<"add plugin error!:"<<libName.toLocal8Bit().data();
if(handle)dlclose(handle);
return false;
}
connect(pluginCore,SIGNAL(sendDataToBus(shared_ptr<PluginMessage>)),this,SLOT(notifyMessage(shared_ptr<PluginMessage>)));
if(plugins.contains(libName)){ //防止同一个库被打开两次
dlclose(plugins[libName].libHandle);
plugins.remove(libName);
}
plugins.insert(libName,std::move(PluginInfo(handle,pluginCore)));
qDebug()<<QString("add plugin:%1 succeed!").arg(libName);
return true;
}

以上是加载、下面是说说智能指针管理内存shared_ptr<PluginMessage>智能指针 管理Pluginmessage 插件集成这个类、去重写类方法

class PLUGINCORESHARED_EXPORT PluginCore:public QObject
{
Q_OBJECT
friend class PluginManager;
protected:
PluginCore();
protected slots:
virtual void init(void);
virtual void onBusReadyRead(shared_ptr<PluginMessage>);
virtual bool isValidMessage(PluginMessage::PluginMessageType type);

protected:
std::unique_ptr<QThread,void(*)(QThread*)> thread;

signals:
void busReadyRead(shared_ptr<PluginMessage>);
void sendDataToBus(shared_ptr<PluginMessage>);
private:
void onValidBUsData(shared_ptr<PluginMessage> data);
};

*********************************智能指针传递的消息类型**********************************************

class PluginMessage
{
public:
enum PluginMessageType{// 枚举消息类型
BSMFrame,
SpatFrame,
RsiFrame,
RsmFrame,
MapFrame,
SystemGlobal,
gnssData,
CanFrame,
OBUTOAPP,
VERSION,
UPGRADE_STATUS,
OTAMESSAGE,
BSMSENDER,
STARUPDATE,
ENDUPDATA,
};

public:
explicit PluginMessage(const char* messageData, int messageSize, PluginMessageType type);
~PluginMessage();
PluginMessage()=default;
PluginMessage(const PluginMessage&)=default;
PluginMessage(PluginMessage&&)noexcept=default;
PluginMessage&operator=(const PluginMessage&)=default;
PluginMessage&operator=(PluginMessage&&)noexcept=default;

public:
int m_messageSize;
const char* m_messageData = NULL;
PluginMessageType m_messageType;
};

 

注意: qRegisterMetaType<PluginMessage>("PluginMessage"); 。。。。。。。。。。//后面还有自己该注册啥就注册啥

要注册Qt消息类型才可以使用信号槽哦

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdgwy.html