MFC中写法:
1、调用DLL接口类 ,下列代码不是完整的,但是功能能满足
xxx.h
HMODULE m_hDLL;
// 加载DLL
bool LoadDll(char* strDLLFileName);
// 实例化接口
int CreateInstance(int argc, char *argv[]);
//启动QT主线程,阻塞
int StartCoreApplication();
//获得QT DLL中实例化的类
void* GetInstance();
// 释放接口实例
void ReleaseInstance(void* &pInterface);
xxx.cpp
typedef int(__cdecl *Func_CreateObject)(int argc, char *argv[]);
typedef int(__cdecl *Func_StartCoreApplication)();
typedef void*(__cdecl *Func_GetObject)();
typedef void(__cdecl *Func_ReleaseObject)(void*&);
// 加载DLL
bool xxx::LoadDll(char* strDLLFileName)
{
CString strInfo;
m_csFileName = strDLLFileName;
m_hDLL = ::LoadLibrary(strDLLFileName);
if (m_hDLL == 0)
return false;
}
return true;
}
// 实例化接口
int xxx::CreateInstance(int argc, char *argv[])
{
int pReturn = 0;
if (m_hDLL != NULL)
{
Func_CreateObject funcCreateObject = (Func_CreateObject)GetProcAddress(m_hDLL, "WD_CreateObject");
pReturn = funcCreateObject(argc, argv);
}
return pReturn;
}
//启动QT主线程
int xxx::StartCoreApplication()
{
int pReturn = 0;
if (m_hDLL != NULL)
{
Func_StartCoreApplication funcStartCoreApplication = (Func_StartCoreApplication)GetProcAddress(m_hDLL, "WD_StartCoreApplication");
pReturn = funcStartCoreApplication();
}
return pReturn;
}
void* xxx::GetInstance()
{
void* pReturn = nullptr;
if (m_hDLL != NULL)
{
Func_GetObject funcGetObject = (Func_GetObject)GetProcAddress(m_hDLL, "WD_GetObject");
pReturn = funcGetObject();
}
return pReturn;
}
// 释放接口实例
void xxx::ReleaseInstance(void* &pInterface)
{
if (m_hDLL != NULL)
{
if (pInterface != NULL)
{
Func_ReleaseObject funcReleaseObject = (Func_ReleaseObject)GetProcAddress(m_hDLL, "WD_ReleaseObject");
funcReleaseObject(pInterface);
}
}
}
2、在MFC中调用的,本次演示同时调用2个DLL
aaa.h
xxx m_Factory1;//接口工厂1
xxx m_Factory2;//接口工厂2
QtObject1_interface* qtObject1; //此对象是带纯虚函数的结构体接口,在QT DLL实例化类中可以Public继承,通过GetInstance()获取实例化类指针强转调用函数
QtObject2_interface* qtObject2; //同上
static DWORD WINAPI ThreadFunc(void* pParam);//QT有主线程,MFC开启线程去调用QT
aaa.cpp
//初始化和启动MFC线程
m_Factory1.LoadDll("QtObject1Lib.dll");
m_Factory2.LoadDll("QtObject2Lib.dll");
DWORD m_dwThreadID;
::CreateThread(NULL, 0, &ThreadFunc, this, 0, &m_dwThreadID);
//MFC线程
DWORD WINAPI aaa::ThreadFunc(void* pParam)
{
aaa* m_p = (aaa*)pParam;
m_p->m_Factory1.CreateInstance(0, nullptr);
m_p->m_Factory2.CreateInstance(0, nullptr);
m_p->m_Factory1.StartCoreApplication();//只需要调用1个DLL启动QT核心线程
return 0;
}
//调用QT类函数
qtObject1= (QtObject1_interface*)m_Factory1.GetInstance();//获得DLL1的实例化类
qtObject2= (QtObject2_interface*)m_Factory2.GetInstance();//获得DLL2的实例化类
int a = qtObject1.ceshi1(a,b,c,....);//调用DLL1实例化类继承的结构体虚函数ceshi1
int b = qtObject2.ceshi2(a,b,c,....);//调用DLL2实例化类继承的结构体虚函数ceshi2
MFC和QT公用的接口
QtObject1_interface.h
struct QtObject1_interface
{
public:
virtual int __cdecl ceshi1(a, b, c,........) = 0;
};
---------------分界线,以上MFC部分代码已经全部写完----------------------------------
QT中的写法
1、创建QT Library C++工程
QtObject1Lib.h
extern "C" __declspec(dllexport) int __cdecl WD_CreateObject(int argc, char *argv[]);
extern "C" __declspec(dllexport) int __cdecl WD_StartCoreApplication();
extern "C" __declspec(dllexport) void *__cdecl WD_GetObject();
extern "C" __declspec(dllexport) void __cdecl WD_ReleaseObject(void *&pObj);
QtObject1Lib.cpp
static void *pObj = nullptr;
__declspec(dllexport) int __cdecl WD_CreateObject(int argc, char *argv[])
{
QCoreApplication *app = QCoreApplication::instance();
if (app == nullptr) {
app = new QCoreApplication(argc, argv);
}
pObj = (QtObject1_interface*) new QTobject1();
qDebug() << "Creat QTobject1 object success!";
return 0;
}
__declspec(dllexport) int __cdecl WD_StartCoreApplication()
{
QCoreApplication *app = QCoreApplication::instance();
qDebug() << "Start QtCoreApplication thread success, Don't start repeatedly!";
return app->exec();
}
__declspec(dllexport) void *__cdecl WD_GetObject()
{
return pObj;
}
__declspec(dllexport) void __cdecl WD_ReleaseObject(void *&pObj)
{
if (pObj != nullptr) {
QTobject1*pObj1 = (QTobject1*) pObj;
delete pObj1;
pObj1 = nullptr;
pObj = nullptr;
}
}
2、创建需要调用的类
QTobject1.h
class QTobject1: public QObject, QTobject1_interface
{
Q_OBJECT
public:
explicit QTobject1(QObject *parent = nullptr);
// QTonject1_interface interface
public:
int __cdecl ceshi1(a, b, c,......);
QTobject1.cpp
QTobject1::QTobject1(QObject *parent)
{
}
int QTobject1::ceshi1(a, b, c,....)
{
//此处无法直接调用connect,会报不在同一线程中,可以调用emit转到QT线程
return 0;
}
---------------分界线,以上QT部分代码已经全部写完----------------------------------
至此,MFC调用QT DLL可以实现并且QT内部信号和槽都可以使用,QT的主线程已经启动。