이 글은 기존에 만들어진 MFC 응용 프로그램에서, 이미 Qt로 만들어진 프로그램을 불러와야 할때 처리방법에 대한 내용을 기술합니다.

 

1. 다음과 같이 Qt 예제를 작성합니다.

qtdll.pro 파일

[code]
TARGET = qtdll
TEMPLATE = lib

DEFINES += QTDLL_LIBRARY

SOURCES += qtdll.cpp \
    dialog.cpp

HEADERS += qtdll.h\
        qtdll_global.h \
    dialog.h

include(qtwinmigrate/src/qtwinmigrate.pri)
INCLUDEPATH += qtwinmigrate/src

unix {
    target.path = /usr/lib
    INSTALLS += target
}

FORMS += \
    dialog.ui
[/code]

 

qtdll_global.h파일

[code]
#ifndef QTDLL_GLOBAL_H
#define QTDLL_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(QTDLL_LIBRARY)
#  define QTDLLSHARED_EXPORT Q_DECL_EXPORT
#else
#  define QTDLLSHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // QTDLL_GLOBAL_H
[/code]

 

qtdll.h 파일

[code]
#ifndef QTDLL_H
#define QTDLL_H

#include "qtdll_global.h"

extern "C" QTDLLSHARED_EXPORT void doIt();

#endif // QTDLL_H
[/code]

 

qtdll.cpp파일

[code]
#include "qtdll.h"
#include "dialog.h"
#include <windows.h>
#include <QMfcApp>

void doIt()
{
    Dialog dialog(0);
    dialog.exec();
}

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved)
{
    char buf[64];
    static bool ownApplication = FALSE;
    if (dwReason == DLL_PROCESS_ATTACH) {
        ownApplication = QMfcApp::pluginInstance(hInstance);
        sprintf(buf,"qtdll DllMain Attach, own:%d\n",ownApplication);
        OutputDebugStringA(buf);
    }
    return TRUE;
}
[/code]

 

doIt 함수에서 호출할 Dialog의 코드는 다음과 같음
dialog.h

[code]
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT
public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
private:
    Ui::Dialog *ui;
};

#endif // DIALOG_H
[/code]

 

dialog.cpp

[code]
#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
}

Dialog::~Dialog()
{
    delete ui;
}
[/code]

 

그리고 한가지가 더 필요한데, qtdll.cpp파일 DllMain함수에서 사용하는 QMfcApp는 https://github.com/qtproject/qt-solutions 에서 다운로드 받아서 압축을 해제 합니다.
위와 같이 코드를 작성후 컴파일을 하면 qtdll.dll 파일이 생성되면서 모든 준비가 끝났습니다.

 

2. MFC에서 호출하기

MFC에서 다음과 같이 qtdll.dll파일을 호출합니다.

또한, 앞서 생성한 qtdll.dll 파일을 MFC 프로젝트 폴더에 복사를 하고,

qtdll.dll의 실행에 필요한 Qt dll파일들(여기 예제에서는 QtCore4.dll, QtGui4.dll두개 필요)을 같이 위치에 복사를 합니다.

[code]
void CmfcqtDlg::OnBnClickedRunButton()
{
	TCHAR szDirectory[MAX_PATH] = {0,};
	::GetCurrentDirectory(sizeof(szDirectory), szDirectory);

	CString path = CString(szDirectory) + "\\qtdll.dll";
	HINSTANCE handle = LoadLibrary(path);
	if (handle == 0)
	{
		TRACE("CmfcqtDlg::OnBnClickedRunButton failed to open qtdll.dll\n");
		return;
	}

	typedef int (*DoItFunc)();
	DoItFunc doItFunc =(DoItFunc)GetProcAddress(handle,"doIt");
	if (handle == 0)
	{
		TRACE("CmfcqtDlg::OnBnClickedRunButton failed to resolve doIt function\n");
		return;
	}

	doItFunc();
	if (handle) FreeLibrary(handle);
}
[/code]

 

위와 같이 qtdll.dll의 doIt함수를 호출하면 다음과 같이 실행됩니다.