Utilice qmake para crear un marco para cargar bibliotecas estáticas y compartidas

Tabla de contenido

1. Establecer un proyecto a gran escala

1.1 Construye una biblioteca estática

1.2 Crear una biblioteca compartida

Dos, llame al archivo de biblioteca generado

Tres, cargar bibliotecas compartidas en tiempo de ejecución

Sobre el complemento

Sobre el embalaje


 

Para conocer la sintaxis de qmake, consulte: http://doc.qt.io/qt-5/qmake-manual.html . Esto es qt5, y qt4 y qt5 se escriben de forma ligeramente diferente.

En términos generales, los proyectos que construimos usando qt creator terminan con .pro, de hecho, lo que está involucrado aquí es la sintaxis qmake.

Además de los archivos .pro, hay archivos .pri, .prf y .prl.

  • No hay mucho que decir sobre el archivo profesional.
  • El i en el PRI es la primera letra i NCLUDE. Es similar a los archivos de encabezado en C y C ++. De todos modos, podemos poner una parte del archivo * .pro en un archivo * .pri y luego incluirlo.
  • El prf f es la característica ( f un aspecto similar) del primer carácter, y el archivo pri debe incluirse en el archivo profesional como CONFIG + = QT.

  • ls link prl de ( L Ink) del primer carácter. Está principalmente relacionado con la generación y el uso de bibliotecas estáticas (las bibliotecas dinámicas también pueden tener este archivo, solo vaya al directorio lib en el directorio de instalación de Qt para echar un vistazo).

Para obtener más información, consulte la publicación del blog " Sobre los archivos pro, pri, prf y prl de qmake ".

Por lo tanto, qmake es particularmente importante para construir un proyecto a gran escala.

Este artículo hace referencia a publicaciones de blog: " Qt para crear y usar bibliotecas compartidas ", " Qt para cargar bibliotecas compartidas en tiempo de ejecución " y " Qt para crear y usar bibliotecas de enlaces estáticos ".

 

1. Establecer un proyecto a gran escala

Primero elija crear un nuevo proyecto, haga clic en otros proyectos, seleccione el proyecto de subdirectorio y luego seleccione la ruta y asígnele un nombre.

El archivo .pro generado en este momento debe ser el siguiente:

TEMPLATE = subdirs
CONFIG += ordered

Luego cree diferentes subproyectos bajo el proyecto, que pueden ser programas ejecutables o archivos de biblioteca. Haga clic derecho para crear un nuevo "nuevo subproyecto".

Por ejemplo, cree un nuevo proyecto de biblioteca aquí e ingrese el siguiente paso después de la selección:

Aquí puede elegir construir una biblioteca compartida, una biblioteca estática o un complemento Qt (complemento Qt).

1.1 Construye una biblioteca estática

Elija crear una biblioteca estática. En este momento, el archivo .pro del subproyecto debe contener lo siguiente:

TARGET = staticLib
TEMPLATE = lib
CONFIG += staticlib

Indica que se generará una biblioteca estática denominada staticLib.

Agregue algunas líneas más a continuación:

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

Indica que el archivo de biblioteca generado se colocará en externlib, y si se compila con depuración, se agregará d al sufijo generado.

Para archivos .hy .cpp, puede escribir varias funciones libremente.

1.2 Crear una biblioteca compartida

El proceso de creación de una biblioteca compartida es el mismo que el de crear una biblioteca estática, pero la selección es diferente. En este momento, el archivo .pro debe ser el siguiente:

TARGET = sharedLib
TEMPLATE = lib
DEFINES += SHAREDLIB_LIBRARY

Indica que se generará una biblioteca compartida denominada sharedLib.

Dado que la biblioteca compartida debe colocarse en el mismo directorio que el programa ejecutable, se deben agregar las siguientes líneas:

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

De manera similar, aquí se agrega d al sufijo compilado en la versión de depuración.

Para archivos .hy .cpp, puede escribir interfaces de función libremente.

Además de los dos archivos de las clases generales de C ++, Qt Creator también nos ayudará a crear un archivo de encabezado llamado {projectName} _global.h para garantizar que se pueda llamar a la macro correcta.

Además, si está escrito en lenguaje C, también debe agregar "C" externa en el archivo de encabezado exportado.

 

Dos, llame al archivo de biblioteca generado

Primero cree un nuevo subproyecto, seleccione Aplicación para generar archivos ejecutables.

Del mismo modo, para el archivo final generado, lo asignamos al directorio de características. En general, el software tendrá una versión de depuración y una versión de lanzamiento para su distinción, y también agregará el siguiente código.

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

Escribir de esta manera es un buen hábito para separar eficazmente el rel generado por debug.

Luego, en el subproyecto, haga clic derecho para agregar la biblioteca. Dado que los proyectos de biblioteca compartida de la biblioteca estática creados anteriormente están todos en el mismo proyecto, puede seleccionar la biblioteca interna.

El nombre de la biblioteca a seleccionar se puede reconocer automáticamente, la plataforma se puede verificar y la versión de depuración se agrega con 'como sufijo'.

Después de agregar, las siguientes líneas se agregarán automáticamente al archivo .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

Parece muy complicado y en realidad es similar a agregar dependencias en un proyecto VS, incluido el directorio donde se encuentran los archivos de encabezado. Tenga en cuenta que el archivo de la biblioteca estática debe asignarse a la carpeta externlib , correspondiente a la compilación anterior.

De manera similar, el proceso de agregar bibliotecas compartidas es el mismo. Después de agregar, se agregará lo siguiente al archivo .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

Básicamente es lo mismo que agregar una biblioteca estática.

 

Con respecto a las bibliotecas estáticas y las bibliotecas compartidas, se requieren ambos archivos .lib durante la compilación. Después de la compilación, los archivos dll o más de la biblioteca compartida deben colocarse en una ubicación donde se pueda encontrar el archivo ejecutable; de ​​lo contrario, el tiempo de ejecución indicará que la dependencia falta y la biblioteca estática se requiere en tiempo de compilación. Las ventajas y desventajas específicas son las siguientes:

  • Al crear una biblioteca compartida, es necesario implementarla en una aplicación Las aplicaciones y bibliotecas asociadas con la biblioteca compartida son muy pequeñas.
  • La vinculación estática generará un archivo ejecutable independiente. La ventaja de esto es que solo se necesitan implementar unos pocos archivos. La desventaja es que el archivo ejecutable será muy grande.

Después de la implementación anterior, podemos llamar a la interfaz de función en la biblioteca estática o biblioteca compartida.

 

Tres, cargar bibliotecas compartidas en tiempo de ejecución

El primero y el segundo hablan sobre cómo implementar en un proyecto completo confiando en los archivos de la biblioteca. De hecho, otra ventaja del archivo de biblioteca compartida es elegir si cargar o no cuando se inicia el programa, es decir, el modo plug-in que solemos llamar.

Qt sugiere la biblioteca QLibrary o QPluginLoader dos formas de cargar bibliotecas compartidas.

Si usa la clase QLibrary, generalmente se usa la función de resolución. Para más detalles, consulte " Qt: Cargando bibliotecas compartidas en tiempo de ejecución ".

Si usa QtPlugin, debe agregar las siguientes líneas:

#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)

El archivo json se utiliza para describir algunas propiedades del complemento.

El código clave del método de llamada específico de QtPlugin es el siguiente:

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();
			}
		}
	}
}

Desde entonces, se ha cargado el complemento.

El efecto de demostración para una demostración es el siguiente:

La interfaz del complemento cargado se mostrará en Tab2.

El código completo del proyecto se puede encontrar en https://github.com/WelinLee/qt_pattern , y se puede compilar tanto en plataformas Windows como Linux.

 

Sobre el complemento

A través de lo anterior, podemos diseñar un pequeño programa de complemento. Al diseñar un programa modular de este tipo, se deben considerar los siguientes puntos:

  • Cómo registrar el complemento;
  • Cómo llamar al complemento;
  • Cómo probar el complemento;
  • Gestión del ciclo de vida de plug-ins;
  • Proporcione información como el nombre, la versión y el estado del complemento, obtenga la lista de complementos, registre el registro de procesamiento del complemento, etc .;
  • Manejo de errores de plug-in.

Para obtener más información, consulte " Comprensión en profundidad del sistema de complementos " y " Creación de su propio sistema de complementos Qt ".

 

Sobre el embalaje

Para la generación del software, si es plataforma Windows se puede utilizar windeploy qt .exe empaquetado.

En Linux, puede usar el comando ldd (deplist = $ (ldd $ exe | awk '{if (match ($ 3, "/")) {printf ("% s", $ 3)}}')) para encontrar lo que el programa necesita dependencias y luego las empaqueta.

 

Supongo que te gusta

Origin blog.csdn.net/u014610460/article/details/84928321
Recomendado
Clasificación