qmake를 사용하여 정적 및 공유 라이브러리를로드하는 프레임 워크 빌드

목차

1. 대규모 프로젝트 수립

1.1 정적 라이브러리 구축

1.2 공유 라이브러리 만들기

둘째, 생성 된 라이브러리 파일 호출

셋, 런타임에 공유 라이브러리로드

플러그인 정보

포장에 대해


 

qmake의 구문은 http://doc.qt.io/qt-5/qmake-manual.html을 참조하십시오 . 이것은 qt5이고 qt4와 qt5는 약간 다르게 작성됩니다.

일반적으로 qt creator를 사용하여 빌드 한 프로젝트는 .pro로 끝납니다. 실제로 여기에 관련된 것은 qmake 구문입니다.

.pro 파일 외에도 .pri, .prf 및 .prl 파일이 있습니다.

  • 프로 파일에 대해 할 말이 많지 않습니다.
  • i in pri는 i nclude의 첫 글자입니다. C와 C ++의 헤더 파일과 비슷하지만 * .pro 파일의 일부를 * .pri 파일에 넣은 다음 포함 할 수 있습니다.
  • prf f는 첫 번째 캐릭터 의 특성 ( f 비슷한 음식)이며 pri 파일은 CONFIG + = QT로 pro 파일에 포함됩니다.

  • ls link prl of ( L Ink) of the first character. 주로 정적 라이브러리 생성 및 사용과 관련이 있습니다 (동적 라이브러리도이 파일을 가질 수 있습니다. Qt 설치 디렉토리 아래의 lib 디렉토리로 이동하여 살펴보십시오).

자세한 내용은 블로그 게시물 " On the pro, pri, prf 및 prl files of qmake "를 참조하십시오.

따라서 qmake는 대규모 프로젝트를 구축하는 데 특히 중요합니다.

이 기사는 " 공유 라이브러리를 만들고 사용하기위한 Qt ", " 런타임에 공유 라이브러리를로드 하기위한 Qt "및 " 정적 링크 라이브러리를 만들고 사용하기위한 Qt "와 같은 블로그 게시물을 참조합니다 .

 

1. 대규모 프로젝트 수립

먼저 새 프로젝트 만들기를 선택하고 다른 프로젝트를 클릭 한 다음 하위 디렉터리 프로젝트를 선택하고 경로를 선택하고 이름을 지정합니다.

이때 생성 된 .pro 파일은 다음과 같아야합니다.

TEMPLATE = subdirs
CONFIG += ordered

그런 다음 프로젝트 아래에 실행 가능한 프로그램 또는 라이브러리 파일이 될 수있는 다른 하위 프로젝트를 만듭니다. 새 "새 하위 프로젝트"를 생성하려면 마우스 오른쪽 버튼을 클릭합니다.

예를 들어 여기에서 새 라이브러리 프로젝트를 만들고 선택 후 다음 단계를 입력합니다.

여기서 공유 라이브러리, 정적 라이브러리 또는 Qt 플러그인 (Qt 플러그인)을 빌드하도록 선택할 수 있습니다.

1.1 정적 라이브러리 구축

정적 라이브러리 빌드를 선택합니다. 현재 하위 프로젝트 .pro 파일에는 다음이 포함되어야합니다.

TARGET = staticLib
TEMPLATE = lib
CONFIG += staticlib

staticLib라는 정적 라이브러리가 생성됨을 나타냅니다.

아래에 몇 줄을 더 추가하십시오.

CONFIG += debug_and_release
CONFIG(debug, debug|release): TARGET = $$join(TARGET,,,d)
DESTDIR = ../../externlib/

생성 된 라이브러리 파일이 externlib 아래에 배치되고 디버그 컴파일 된 경우 생성 된 접미사에 d가 추가됨을 나타냅니다.

.h 및 .cpp 파일의 경우 다양한 함수를 자유롭게 작성할 수 있습니다.

1.2 공유 라이브러리 만들기

공유 라이브러리를 생성하는 과정은 정적 라이브러리를 생성하는 과정과 동일하지만 선택 사항이 다릅니다. 이때 .pro 파일은 다음과 같아야합니다.

TARGET = sharedLib
TEMPLATE = lib
DEFINES += SHAREDLIB_LIBRARY

sharedLib이라는 공유 라이브러리가 생성됨을 나타냅니다.

공유 라이브러리는 실행 프로그램과 같은 디렉토리에 위치해야하므로 다음 행을 추가해야합니다.

CONFIG += debug_and_release
CONFIG(debug, debug|release): TARGET = $$join(TARGET,,,d)
CONFIG(debug, release|debug): DESTDIR = ../../debug/
CONFIG(release, release|debug): DESTDIR = ../../release/

마찬가지로 여기서 d는 디버그 버전에서 컴파일 된 접미사에 추가됩니다.

.h 및 .cpp 파일의 경우 함수 인터페이스를 자유롭게 작성할 수 있습니다.

일반 C ++ 클래스의 두 파일 외에도 Qt Creator는 올바른 매크로가 호출 될 수 있도록 {projectName} _global.h라는 헤더 파일을 만드는 데 도움이됩니다.

또한 C 언어로 작성된 경우 내 보낸 헤더 파일에 extern "C"도 추가해야합니다.

 

둘째, 생성 된 라이브러리 파일 호출

먼저 새 하위 프로젝트를 만들고 응용 프로그램을 선택하여 실행 파일을 생성합니다.

마찬가지로 생성 된 최종 파일의 경우 기능 디렉토리에 할당합니다. 일반적으로 소프트웨어에는 구분을위한 디버그 버전과 릴리스 버전이 있으며 다음 코드도 추가됩니다.

CONFIG(debug, release|debug): DESTDIR = ../../debug/
CONFIG(release, release|debug): DESTDIR = ../../release/

이런 식으로 작성하는 것은 디버그에 의해 생성 된 rel을 효과적으로 분리하는 좋은 습관입니다.

그런 다음 하위 프로젝트에서 마우스 오른쪽 버튼을 클릭하여 라이브러리를 추가합니다. 이전에 생성 된 정적 라이브러리 공유 라이브러리 프로젝트는 모두 동일한 프로젝트에 있으므로 내부 라이브러리를 선택할 수 있습니다.

선택할 라이브러리의 이름을 자동으로 인식하고 플랫폼을 확인할 수 있으며 디버그 버전은 접미사로 'd'가 추가됩니다.

추가 한 후 다음 줄이 .pro 파일에 자동으로 추가됩니다.

win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../externlib/ -lstaticLib
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../externlib/ -lstaticLibd
else:unix: LIBS += -L$$OUT_PWD/../../externlib/ -lstaticLib

INCLUDEPATH += $$PWD/../staticLib
DEPENDPATH += $$PWD/../staticLib

win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../externlib/libstaticLib.a
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../externlib/libstaticLibd.a
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../externlib/staticLib.lib
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../externlib/staticLibd.lib
else:unix: PRE_TARGETDEPS += $$OUT_PWD/../../externlib/libstaticLib.a

매우 복잡해 보이며 실제로 헤더 파일이있는 디렉토리를 포함하여 VS 프로젝트에 종속성을 추가하는 것과 유사합니다. 정적 라이브러리 파일 은 이전 빌드에 해당하는 externlib 폴더에 할당되어야합니다 .

마찬가지로 공유 라이브러리를 추가하는 과정도 동일하며 추가 후 .pro 파일에 다음 내용이 추가됩니다.

win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../release/ -lsharedLib
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../debug/ -lsharedLibd
else:unix: LIBS += -L$$OUT_PWD/../sharedLib/ -lsharedLib

INCLUDEPATH += $$PWD/../sharedLib
DEPENDPATH += $$PWD/../sharedLib

기본적으로 정적 라이브러리를 추가하는 것과 같습니다.

 

정적 라이브러리와 공유 라이브러리의 경우 컴파일 중에 .lib 파일이 모두 필요합니다. 컴파일 후 공유 라이브러리의 dll 정도 파일을 실행 파일이있는 위치에 배치해야합니다. 그렇지 않으면 런타임에서 종속성을 묻는 메시지가 표시됩니다. 누락 및 정적 라이브러리 컴파일시 필요합니다. 구체적인 장점과 단점은 다음과 같습니다.

  • 공유 라이브러리를 생성 할 때 응용 프로그램에 배포해야하며 공유 라이브러리와 관련된 응용 프로그램 및 라이브러리는 매우 작습니다.
  • 정적 링크는 독립적 인 실행 파일을 생성합니다. 이것의 장점은 몇 개의 파일 만 배포하면된다는 것입니다. 단점은 실행 파일이 매우 커진다는 것입니다.

위의 배포 후 정적 라이브러리 또는 공유 라이브러리에서 함수 인터페이스를 호출 할 수 있습니다.

 

셋, 런타임에 공유 라이브러리로드

위의 첫 번째와 두 번째는 라이브러리 파일에 의존하면서 전체 프로젝트에 배포하는 방법에 대해 설명합니다. 사실 공유 라이브러리 파일의 또 다른 장점은 프로그램이 시작될 때로드할지 여부, 즉 우리가 자주 호출하는 플러그인 모드를 선택하는 것입니다.

Qt는 공유 라이브러리를로드하는 두 가지 방법으로 QLibrary 라이브러리 또는 QPluginLoader를 제안합니다.

QLibrary 클래스를 사용하는 경우 일반적으로 resolve 함수가 사용됩니다. 자세한 내용은 " Qt : 런타임에 공유 라이브러리로드 "를 참조하십시오 .

QtPlugin을 사용하는 경우 다음 줄을 추가해야합니다.

#define PluginID   "org.qt-project.Qt.Examples.plugin.IPluginUi"
Q_DECLARE_INTERFACE(IPluginUi, PluginID)

Q_PLUGIN_METADATA(IID PluginID FILE "pluginForm.json")
Q_INTERFACES(IPluginUi)

json 파일은 플러그인의 일부 속성을 설명하는 데 사용됩니다.

QtPlugin의 특정 호출 방법의 키 코드는 다음과 같습니다.

QStringList filters;
filters << "*.dll" << "*.so";      //在插件所在的文件夹下筛选后缀为dll或so结尾的文件
pluginDir.setNameFilters(filters);
foreach (QString filename, pluginDir.entryList(QDir::Files))
{
	QPluginLoader *pluginload = new QPluginLoader(pluginDir.absoluteFilePath(filename));
	pluginload->setLoadHints(QLibrary::ExportExternalSymbolsHint | QLibrary::ResolveAllSymbolsHint);
	if(pluginload->load())
	{
		QObject *obj = pluginload->instance();
		if(obj)
		{
			IPluginUi *plugin = qobject_cast<IPluginUi*>(obj);
			if(plugin)
			{
				QWidget *widget = plugin->PluginUi();
				QString str_sn = plugin->getSerialNumber();

				QString class_name = pluginload->metaData().value("className").toString();
				ui->textEdit->append("export class: " + class_name);
				QJsonObject json = pluginload->metaData().value("MetaData").toObject();
				QString str_author = json.value("author").toString();
				QString str_date = json.value("date").toString();
				QString str_license = json.value("license").toString();
				QString str_version = json.value("version").toString();
				QJsonArray array = json.value("changelog").toArray();
			}
		}
	}
}

그 이후로 플러그인이로드되었습니다.

데모의 데모 효과는 다음과 같습니다.

로드 된 플러그인 인터페이스는 Tab2에 표시됩니다.

프로젝트의 전체 코드는 https://github.com/WelinLee/qt_pattern 에서 찾을 수 있으며 Windows 및 Linux 플랫폼 모두에서 컴파일 할 수 있습니다.

 

플러그인 정보

위를 통해 작은 플러그인 프로그램을 설계 할 수 있습니다. 이러한 모듈 식 프로그램을 설계 할 때 다음 사항을 고려해야합니다.

  • 플러그인 등록 방법
  • 플러그인 호출 방법
  • 플러그인 테스트 방법
  • 플러그인 수명주기 관리;
  • 플러그인의 이름, 버전 및 상태와 같은 정보를 제공하고, 플러그인 목록을 가져오고, 플러그인의 처리 로그를 기록합니다.
  • 플러그인 오류 처리.

자세한 내용은 " 플러그인 시스템에 대한 심층 이해 "및 " 자신의 Qt 플러그인 시스템 구축 "을 참조하십시오.

 

포장에 대해

소프트웨어 생성을 위해 Windows 플랫폼이라면 windeploy qt .exe 패키지를 사용할 수 있습니다 .

Linux에서는 ldd 명령 (deplist = $ (ldd $ exe | awk '{if (match ($ 3, "/")) {printf ( "% s", $ 3)}}'))을 사용하여 무엇을 찾을 수 있습니다. 프로그램에는 종속성이 필요하고 패키지화됩니다.

 

추천

출처blog.csdn.net/u014610460/article/details/84928321