QT跟VC++结合来进行插件的验证机制(遍历vtable,保证虚函数的个数一致,也可使用Q_INVOKABLE宏定义)

由于最近公司要开发一个以C++插件机制为主的,主要有一个问题就是C++的二进制兼容性的问题。
一旦类使用虚函数,只要随便改动下增删查改下头文件的虚函数,就会导致程序在跑的时候进行乱跳,因为这个时候exe跟dll里面的vtable模型是不一致的

刚好程序是使用QT开发了,所以就用了两种方式来保证头文件一致才能进行程序的加载

1. 利用QT的MOC机制
QT的MOC机制里面有一个Q_INVOKABLE的宏定义,可以让moc生成类成员函数的相关信息,
然后利用QObject里面的method来获取对应的函数参数和函数顺序
用于保证虚函数的顺序,参数一致
具体查看QObject的相关文档
http://doc.qt.io/qt-5/qobject.html
http://doc.qt.io/qt-5/qmetaobject.html
http://doc.qt.io/qt-5/qmetamethod.html
从qobject里面或者metaobject再获取metamethod,即可获取指定的函数信息

2. 遍历vtable,保证虚函数的个数一致。如何获取vtable的在网上有很多文章,下面主要是针对VS2015的编译器代码

下面代码主要做的事情:
1. 保证传入的程序有虚函数
2. 保证T不指针类型
3. 获取vtable
4. 遍历vtable一直遇到0

template <class T>

int vtableLength(T &object)

{

    static_assert(std::is_polymorphic<T>::value,

                  "at least has one virtual function");

    static_assert(!std::is_pointer<T>::value,

                  "type not allow pointer");

    int* vptr = (int*)&object;

    int* vtable = (int*)*vptr;

    int len = 0;

    for (int i = 0; vtable[i] != 0; i++)

    {

        len++;

    }

    return len;

}

https://www.cnblogs.com/linyilong3/p/6750516.html

原文地址:https://www.cnblogs.com/findumars/p/9410806.html

时间: 2024-10-08 23:33:02

QT跟VC++结合来进行插件的验证机制(遍历vtable,保证虚函数的个数一致,也可使用Q_INVOKABLE宏定义)的相关文章

VC中预处理指令与宏定义详解

刚接触到MFC编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C语言的一个强大工具.使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能. 一个经典的例子 使用预处理与宏定义最经典的例子莫过于加在一个头文件中以避免头文件被两次编译.试想这种的情况,有一个文件headerfile.h 它被包含在headerfile1.h中,同时在headerfile2.h 中也被包含了,现在有一个CPP文件,implement.cpp 包含了headerfi

【大话QT之十五】ctkPluginFrameWork插件系统Windows下编译

使用ctkPluginFramework作为插件系统框架的确有着众多开发上的优势.最近收到一些站内信,大家都想使用ctkPluginFramework但是不知道如何编译,这篇教程就来讲一讲ctkPluginFramework插件系统在Windows下的编译过程. 准备条件: 1. 安装Git,我们通过它来下载CTK的源码. 2. 安装CMake,我们用它来生成vs下的sln解决方案文件. 相关站点: 1. CTK的官网:http://www.commontk.org/index.php/Main

Qt打开外部程序和文件夹需要注意的细节(Qt调用VC写的动态库,VC需要用C的方式输出函数,否则MinGW32编译过程会报错)

下午写程序中遇到几个小细节,需要在这里记录一下. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 QProcess *process = new QProcess(this);     QFileInfo fileinfo(appUrl);     QString appPath = QApplication::applicationDirPath()+SAVEDIR+"/"+fileinfo.fileName();     bool res = proce

Qt5的插件机制(1)--Qt 框架中的插件加载机制概述

概述 Qt的源码中通过 Q<pluginType>Factory.Q<pluginType>Plugin 和 Q<pluginType> 这三个类实现了Qt的插件加载机制, 这个机制可用于加载特定种类的插件.比如通过 QPlatformIntegrationFactory\QPlatformIntegrationPlugin\QPlatformIntegration 三个类可以实现平台类QPA插件(PlatformIntegration)的加载,通过QPlatformI

Qt、Vc下用fopen打开中文名字的文件

在做一个Qt项目的时候,完成上传文件时,通过fopen打开文件用来读时发现fopen不能打开中文的文件名,自己在网查找一下,解决方法如下 参考:http://weidaohang.org/wangluo/h/index.php?q=aHR0cDovL3d3dy5qYjUxLm5ldC9hcnRpY2xlLzUxOTY2Lmh0bQ%3D%3D 代码如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 boolUTF8ToUnicode(

Qt添加驱动——Qt数据库之添加MySQL驱动插件

Qt数据库之添加MySQL驱动插件(1) 现在可用的数据库驱动只有3种,在Qt中,我们需要自己编译其他数据库驱动的代码,让它们以插件的形式来使用.下面我们就以现在比较流行的MySQL数据库为例,说明一下怎样在Qt Creator中添加数据库驱动插件.在讲述之前,我们先看一下Qt Creator中数据库的插件到底放在哪里. 我们进入Qt Creator的安装目录,然后进入相对应的文件夹下,比方我这里是 D:Qt2010.02.1qtpluginssqldrivers 在这里我们可以看见几个文件,如

BrnShop开源网上商城第三讲:插件的工作机制

这几天BrnShop的开发工作比较多,所以这一篇文章来的晚了一些,还请大家见谅呀!还有通知大家一下BrnShop1.0.312版本已经发布,此版本添加了报表统计等新功能,需要源码的园友可以点此下载.好了,我们现在进入今天的正题.关于BrnShop插件内容比较多,所以我分成两篇文章来讲解,今天先讲第一部分内容:插件的工作机制. 对于任意一种插件机制来说,基本上只要解决以下三个方面的问题,这个插件机制就算成功了.这三个方面如下: 插件程序集的加载 视图文件的路径和编译 插件的部署 首先是插件程序集的

[Qt解错篇]报错:error: undefined reference to vtable for ClassName

一.问题描述: 编译工程时报错:error: undefined reference to vtable for ClassName,如图示: 二.问题分析: 造成这种错误的原因很多,甚至在纯C++编程过程中也可能出现.下面根据自己情况,具体问题具体分析. 原因:在原先没有Q_OBJECT关键字的工程中添加了该关键字,但是没有执行qmake,直接编译导致出现该错误. 三.例子: 原先工程的类建立: class CAppConfig { public: CAppConfig(void); CApp

Qt设置窗口的初始大小(使用sizeHint这个虚函数)

我们用qt创建一个窗口,先后显示它,代码如下: class Mywindow : public QMainWindow{ ..... } int main( int argc, char** argv ) { QApplication app( argc, argv ); Mywindow wind; wind.show(); return app.exec();} 发现窗口很小,查看它的方法,以及他的父类widget的方法,发现有个方法像是设置其初始大小的,setBaseSize,调用这个方法