VS2010~Qt封装带界面的纯虚类动态库

在vs-qt环境搭好的前提下,按照下面的步骤操作即可:

1、打开vs2010,文件 --》新建 --》项目,选择Qt5 Projects --》Qt LibraryVS2010~Qt封装带界面的纯虚类动态库_第1张图片
2、在项目名称和位置设置好后,点击确定,然后下一步,到Project Settings界面,带界面的话勾选GUI,然后点击完成即可
VS2010~Qt封装带界面的纯虚类动态库_第2张图片
3、然后会生成三个文件,这三个文件其实没有用,可以删掉。然后新建一个虚基类,这个虚基类的头文件我们是要暴露给用户的,所以尽量避免头文件的包含,另外我这里使用了结构体,所以还需要提供一个放结构体的类,然后就是新建一个继承虚基类并实现其纯虚函数方法的子类,具体代码如下:

ibaseclass.h

#ifndef IBASECLASS_H
#define IBASECLASS_H

#include "common.h"

class IBaseClass
{
public:
	// 加载学生信息
	virtual void LoadStudentInfo(QList<Student> &qlist) = 0;
	// 获取学生信息
	virtual QList<Student> GetAllStudentInfo() = 0;
};

/**
 * @brief  createInfoWidget接口创建了一个学生信息显示窗口的void *指针,该指针实际上是一个QWidget*的指针
 *
 * @param  parent 父窗口,默认为空
 * @return 返回学生信息显示窗口的void *类型指针
 */
extern "C" __declspec(dllexport) void * __cdecl createInfoWidget(QWidget *parent = 0);

/**
 * @brief  getInfoWidget接口将void *转换成IBaseClass *对象指针
 *
 * @param  voidPlotWidget 学生信息显示窗口的void *类型指针
 * @return 返回IBaseClass类型的指针,可以调用IBaseClass类的LoadStudentInfo,GetAllStudentInfo2个接口
 */
extern "C" __declspec(dllexport) IBaseClass *__cdecl getInfoWidget(void *voidInfoWidget);

/**
 * @brief  destroyInfoWidget接口是销毁IBaseClass *类型的学生信息显示窗口对象指针
 *
 * @param  voidInfoWidget IBaseClass *类型的学生信息显示窗口对象指针
 */
extern "C" __declspec(dllexport) void __cdecl destroyInfoWidget(void *voidInfoWidget);
#endif // IBASECLASS_H

ibaseclass.cpp

#include 
#include 
#include 
#include "mytest.h"
#include "ibaseclass.h"

void * __cdecl createInfoWidget(QWidget *parent)
{
	QWidget* pwidget = new MyTest(parent); //MyTest继承QWidget,所以也属于QWidget
	if (parent != NULL)
	{
		QMainWindow* pMainWindow =  dynamic_cast<QMainWindow*>(parent); //这里指定父窗口使用QMainWindow,所以加以判断
		Q_ASSERT(pMainWindow); //对pMainWindow断言,判断parent是否属于QMainWindow及其子类
		if (pMainWindow == NULL)
		{
			return NULL;
		}
		pMainWindow->setCentralWidget(pwidget);
	}
	return (void *)pwidget; //最后返回一个void *指针
}

IBaseClass *__cdecl getInfoWidget(void *voidInfoWidget)
{
	//通过createInfoWidget返回的void *指针转换成为QWidget *,
	//看似这一步有点多余,但这是比较稳的操作
	//这里注意:指针转换之前怎么转换来的,需要一步步再转换回去,例如
	//要从void *-->QWidget *-->MyTest *-->IBaseClass*
	//不能直接从void *-->IBaseClass*,这样会出错
	QWidget* pwidget = (QWidget*)voidInfoWidget;
	MyTest*pInfoWidget = dynamic_cast<MyTest*>(pwidget);
	Q_ASSERT(pInfoWidget); //对pInfoWidget断言,判断pInfoWidget是否属于MyTest及其子类
	if(pInfoWidget == NULL)
	{
		return NULL;
	}
	IBaseClass* pIBaseClass =  dynamic_cast<IBaseClass*>(pInfoWidget); //将MyTest*转换成IBaseClass*,供外部调用
	return pIBaseClass;
}

void __cdecl destroyInfoWidget(void *voidInfoWidget)
{
	if (voidInfoWidget != NULL)
	{
		delete voidInfoWidget;
	}
	voidInfoWidget = NULL;
}

common.h

#ifndef COMMON_H
#define COMMON_H

#include 
#include 

struct Student
{
	QString strClass;
	QString strName;
	QString strSex;
	QString strNo;
};
Q_DECLARE_METATYPE(Student);

#endif //COMMON_H

mytest.h

#ifndef MYTEST_H
#define MYTEST_H

#include 
#include "ui_mytest.h"
#include "common.h"
#include "ibaseclass.h"
class MyTest : public QWidget, public IBaseClass
{
	Q_OBJECT

public:
	MyTest(QWidget *parent = 0);
	~MyTest();

protected://IBaseClass
	virtual void LoadStudentInfo(QList<Student> &qlist);
	virtual QList<Student> GetAllStudentInfo();

private:
	Ui::MyTestClass ui;
};

#endif // MYTEST_H

mytest.cpp

#include "mytest.h"

MyTest::MyTest(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
}

MyTest::~MyTest()
{

}

void MyTest::LoadStudentInfo(QList<Student> &qlist)
{
	foreach(const Student &s, qlist)
	{
        ui.class_lineEdit->setText(s.strClass);
		ui.name_lineEdit->setText(s.strName);
		ui.sex_lineEdit->setText(s.strSex);
		ui.no_lineEdit->setText(s.strNo);
	}
}

QList<Student> MyTest::GetAllStudentInfo()
{
	QList<Student> qlist;
	Student s;
	s.strClass = ui.class_lineEdit->text();
	s.strName = ui.name_lineEdit->text();
	s.strSex = ui.sex_lineEdit->text();
	s.strNo = ui.no_lineEdit->text();
	qlist.push_back(s);
	return qlist;
}

mytest.ui
由于xml太长也很简单就只截个图了
VS2010~Qt封装带界面的纯虚类动态库_第3张图片
选中项目名称,右键–》生成,生成成功后会在win32/Debug目录下生成dll,然后提供ibaseclass.h,common.h,和MyDll.dll这三个文件就可以动态加载使用了,见下一篇博客

源码:
https://github.com/BlairHao/MyDll

你可能感兴趣的:(VS-Qt工作总结,c++,qt5,虚基类动态库,纯虚函数接口封装)