MFC调用QT库

首先说下版本:VS2013+qt-opensource-windows-x86-msvc2013-5.7.0.exe

插件:VS:VA_X_Setup2073.exe  QT:qt-vs-addin-1.2.5.exe    

(使用qtwinmigrate实现)  下载地址:qt-solutions.rar

1.在qtwinmigrate中的qtdll中,只要使用main.cpp的如下代码实现动态库模块的引用:

//name: DLL程序入口点函数
//hInstance参数:指向DLL本身的实例句柄
//dwReason参数:指明了DLL被调用的原因,可以有以下4个取值:
//DLL_PROCESS_ATTACH:当DLL被进调用<<第一次> 调用时,导致DllMain函数被调用
//DLL_PROCESS_DETACH:当DLL被从进程的地址空间解除映射时,系统调用了它的DllMain
//DLL_THREAD_ATTACH:当进程创建一线程时,系统查看当前映射到进程地址空间中的所有DLL文件映像
//DLL_THREAD_DETACH:如果线程调用了ExitThread来结束线程(线程函数返回时,系统也会自动调用ExitThread
//lpReserved参数:保留,目前没什么意义
BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpvReserved*/ )
{
    static bool ownApplication = FALSE;
    if ( dwReason == DLL_PROCESS_ATTACH ) {
        ownApplication = QMfcApp::pluginInstance( hInstance );//创建一个QApplication对象
    }
    if ( dwReason == DLL_PROCESS_DETACH && ownApplication ) {
        delete qApp;
    }
    return TRUE;
}
//动态库可以提供的接口
//__declspec(dllexport):可以直接定位到动态库中的函数地址
extern "C" __declspec(dllexport) bool showDialog( HWND parent, void * pMfc = NULL, int (*p)(void*) = NULL, bool canDrag = false)
{
    pWin = new QWinWidget(parent);
    pWin->showCentered();
    pWidget = new PieWidget(pWin, pMfc, p, canDrag);
    RECT r;
    GetWindowRect(pWin->parentWindow(), &r);
    pWidget->move((r.right-r.left-pWidget->width())/2+r.left, (r.bottom-r.top-pWidget->height())/2+r.top);
    pWidget->show();
    return TRUE;
}
//动态库关闭接口
extern "C" __declspec(dllexport) void closeDialog()
{
    if (pWin) {
        delete pWin;
        pWin = NULL;
    }
}

以上是动态库的极简的模块接口,一个是展示接口,一个是关闭接口,如果自己的动态库还需要其他的接口(肯定不止这两个接口),可以按照这两个接口方式进行开发,当让也可以在QT的界面添加控件回调MFC的函数,

PieWidget::PieWidget(QWidget *parent, void *pMfc, int (*p)(void*), bool canDrag):    QWidget(parent),    ui(new Ui::PieWidget),    m_pMfc(pMfc),    m_canDrag(canDrag),    m_pCallback(p)
{
    ui->setupUi(this);
    //add your code
}

其中:QWidget *parent是继承Qt界面父控件的对象,void *pMfc是mfc程序的函数指针,m_pCallback是回调函数的指针,m_canDrag是bool类型的状态变量

编译通过完成之后,MFC调用QT库_第1张图片

需要在这里面配置mfc编译好的EXE文件,放到qt编译版本(relaese/debug)的同级目录下,调试的话可以在Qt下面调试(需要安装CDB调试器),也可以在MFC下调试,这个相对方便些

接下来就是mfc的编写程序,可以在MFC的UI界面添加自己需要的控件,调用方式

void CsecondMFCDlg::OnBnClickedButton1()
{
    // TODO: 在此添加控件通知处理程序代码
    if (m_hDLL) { // 已加载
        return;
    }

    const char* dllName = "xxxx.dll";//qt编译好的动态库
    m_hDLL = LoadLibrary(dllName); // 如果失败,则返回值为NULL

    int index = ((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel();
    bool canDrag = index;
    if (m_hDLL != NULL)
    {
        typedef bool(*pShow)(HWND parent,void *pMfc, int (*p)(void*), bool canDrag);
        int(*pCallback)(void*) = qtCallback;
        pShow fp1 = pShow(GetProcAddress(m_hDLL, "showDialog"));
        if (fp1 != NULL)
        {
            fp1(theApp.m_pMainWnd->m_hWnd, this, pCallback, canDrag); // 
        }
        //FreeLibrary(m_hDLL);
        //m_hDLL = NULL;
    }
    else
    {
        CString strInfo("Cannot Find dll");

        MessageBox(strInfo);
    }
}

最后就是调试环节了,其中的问题多半是百度帮忙。

你可能感兴趣的:(q't)