前言
项目开发使用QT + VS, 在过程中用到了Active组件,平常接触少,所以花了一些时间研究了一下,过程中也遇到不少坑,做篇文章作为记录参考。
创建Active组件
QT提供两种库导出形式,一种是DLL动态库,一种就是Active组件(active是一个microsoft的术语,它指的是一组包括控件、dll、active文档的组件,通常以动态链接库的形式存在。),值得注意的是QT的库是可以带UI图形界面的,这和纯C++不同,但使用时候加载配置方式相似。创建Actvie工程,选择Qt ActiveQT Server。(以下需要配置QT + VS开发环境)
创建工程ActiveX
QAXFACTORY_DEFAULT宏
主要是导出COM组件的ID,依据官方说明,参数含义如下
QAXFACTORY_DEFAULT(ActiveX, // QWiget class,
"{2c13fb28-1776-405a-9eea-8b68a0a43a25}", // class ID
"{f73f1784-c32f-4759-a029-a47ea3a3016a}", //interface ID
"{f6b779b9-d25e-43f2-a9ab-bf542fd49645}", // event interface ID
"{391d4c67-17e0-4a3f-81b6-7f02e0fe5f2d}", // type library ID
"{82ac53a9-7842-4fc4-891f-042a8d324bbb}" // application ID
)
较为关键是Class ID,加载COM组件主要通过这个ID进行标识。
调用
在ActiveQT组件中,通过QT Designer添加一个QButton按钮,然后编译组件工程。编译完成后会注册到系统上。
创建QAxWidget对象,通过ClassID加载控件。
控件实现
需要注意如果包含#include< QAxWidget> 编译不通过,需要加载包含QT lib库Qt5AxContainer.lib如下图:
可在QT Project Setting 中设置
调用Active接口传参
Active组件调用方式通过动态加载,调用方式一般使用dynamicCall, 传递参数使用QList<QVariant>参数列表,如下图:
返回值可以通过dynamicCall返回值获取,另一种方法就是通过参数了列表QString strRetVal = input.at(2).toString();
需要注意声明函数要使用public slots, 否则会出现: dynamicCallHelper:XXXX: No such property in错误。
关于传递指针问题
定义ActiveQT提供的接口,参数不要使用非QT标准类型,使用QVariant中定义的类型,对于必须要传递指针的情况可以使用QByteArray
传递字符指针
传递字符指针可以使用如果只是QT类型可以使用QString,如果有需求需要使用非QT对象,为了灵活可以使用QByteArray,传参数的时候可以使用标准std::string。
组件接口实现
void ActiveX::OnAdd(QByteArray ba)
{
QString str(ba);
qDebug() << str;
}
调用
QtGuiApplication1::QtGuiApplication1(QWidget *parent)
: QMainWindow(parent)
{
.......
………
std::string str = "TestString";
QVariant param(str.data());
QList<QVariant> inplist;
inplist << param;
qw->dynamicCall("OnAdd(QByteArray ba)", inplist);
}
传递结构体指针
传递结构体指针相对比较麻烦。
结构体定义:
typedef struct
{
int age;
char name[20];
}Student;
组件接口实现
void ActiveQtServer1::OnAdd(QByteArray ba)
{
Student * student = (Student *)ba.data();
qDebug() << student ->age << "---" << student ->name;
}
调用
QtGuiApplication1::QtGuiApplication1(QWidget *parent)
: QMainWindow(parent)
{
.......
………
Student student; // 定义结构体
student.age = 100;
student.Name = AFK;
QByteArray ba;
ba.resize(sizeof(Person));
std::memcpy(ba.data(), &persion, sizeof(Person)); //赋值
QVariant param(ba);
QList<QVariant> inplist;
inplist << param;
qw->dynamicCall("OnAdd(QByteArray ba)", inplist);
}
同时也可以传递数组
persionNum[2];
std::memcpy(ba.data(), & persionNum, sizeof(persionNum));