在自己的Qt应用程序中使用自己的静态库

时间:2016-02-27 20:32:32

标签: c++ qt

How to create a library with Qt and use it in an application之后,我能够在自己的Qt应用中创建和使用自己的共享库。

在本教程中,我到达Creating a static library部分,我可能(或不)成功理解。我能够构建libtest.a但是当我尝试使用它时,我得到了:

15:35:25: Running steps for project loadTestLib...
15:35:25: Starting: "C:\Qt\Qt5.5.1\5.5\mingw492_32\bin\qmake.exe" C:\Users\User\Downloads\library\client\static\loadTestLib.pro -r -spec win32-g++
15:35:27: The process "C:\Qt\Qt5.5.1\5.5\mingw492_32\bin\qmake.exe" exited normally.
15:35:27: Starting: "C:\Qt\Qt5.5.1\Tools\mingw492_32\bin\mingw32-make.exe" 
C:/Qt/Qt5.5.1/Tools/mingw492_32/bin/mingw32-make -f Makefile.Release
mingw32-make[1]: Entering directory 'C:/Users/User/Downloads/library/client/static'
g++ -c -pipe -fno-keep-inline-dllexport -O2 -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I. -I. -I.. -I..\testlib -IC:\Qt\Qt5.5.1\5.5\mingw492_32\include -IC:\Qt\Qt5.5.1\5.5\mingw492_32\include\QtWidgets -IC:\Qt\Qt5.5.1\5.5\mingw492_32\include\QtGui -IC:\Qt\Qt5.5.1\5.5\mingw492_32\include\QtANGLE -IC:\Qt\Qt5.5.1\5.5\mingw492_32\include\QtCore -Irelease -IC:\Qt\Qt5.5.1\5.5\mingw492_32\mkspecs\win32-g++  -o release\main.o ..\main.cpp
g++ -Wl,-s -Wl,-subsystem,windows -mthreads -o release\client.exe release/main.o  -lmingw32 -LC:/Qt/Qt5.5.1/5.5/mingw492_32/lib -lqtmain -lshell32 -L../testlib/static/release -ltest -lQt5Widgets -lQt5Gui -lQt5Core 
release/main.o:main.cpp:(.text+0x2d): undefined reference to `_imp___ZN6WidgetC1Ev'
Makefile.Release:77: recipe for target 'release\client.exe' failed
mingw32-make[1]: Leaving directory 'C:/Users/User/Downloads/library/client/static'
release/main.o:main.cpp:(.text+0x62): undefined reference to `_imp___ZTV6Widget'
release/main.o:main.cpp:(.text+0xa6): undefined reference to `_imp___ZTV6Widget'
C:/Qt/Qt5.5.1/Tools/mingw492_32/bin/../lib/gcc/i686-w64-mingw32/4.9.2/../../../../i686-w64-mingw32/bin/ld.exe: release/main.o: bad reloc address 0x13 in section `.eh_frame'
C:/Qt/Qt5.5.1/Tools/mingw492_32/bin/../lib/gcc/i686-w64-mingw32/4.9.2/../../../../i686-w64-mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
mingw32-make[1]: *** [release\client.exe] Error 1
makefile:34: recipe for target 'release' failed
mingw32-make: *** [release] Error 2
15:35:32: The process "C:\Qt\Qt5.5.1\Tools\mingw492_32\bin\mingw32-make.exe" exited with code 2.
Error while building/deploying project loadTestLib (kit: Desktop)
When executing step "Make"
15:35:32: Elapsed time: 00:06.

以下是图书馆的代码:

test.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TEMPLATE = lib
CONFIG += staticlib

CONFIG(debug, debug|release) {
    DESTDIR = debug
} else {
    DESTDIR = release
}

OBJECTS_DIR = $$DESTDIR
MOC_DIR = $$DESTDIR
RCC_DIR = $$DESTDIR
UI_DIR = $$DESTDIR

DEPENDPATH += . ..

INCLUDEPATH += . ..

SOURCES += ../test.cpp

HEADERS += ../test.h

DEFINES += TEST

test.h

#include <QtGui>

#if defined TEST
#define TEST_COMMON_DLLSPEC Q_DECL_EXPORT
#else
#define TEST_COMMON_DLLSPEC Q_DECL_IMPORT
#endif

#include <QWidget>

class TEST_COMMON_DLLSPEC Widget : public QWidget
{
    Q_OBJECT
public:
    Widget();
};

TEST.CPP

#include <QtGui>
#include "test.h"

Widget::Widget() : QWidget() {}

以下是客户端应用的代码:

loadTestLib.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = client

TEMPLATE = app

CONFIG(debug, debug|release) {
    DESTDIR = debug
} else {
    DESTDIR = release
}

OBJECTS_DIR = $$DESTDIR
MOC_DIR = $$DESTDIR
RCC_DIR = $$DESTDIR
UI_DIR = $$DESTDIR

SOURCES += ../main.cpp

DEPENDPATH += . ../testlib

INCLUDEPATH += . .. ../testlib

LIBS += -L../testlib/static/release -ltest

的main.cpp

#include <QApplication>

#include "testlib/test.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Widget w;
    w.resize(200,200);
    w.show();

    return a.exec();
}

我失踪了什么?

1 个答案:

答案 0 :(得分:1)

正如在你的问题的评论中已经说过的那样,动态链接所需的宏在静态链接中引起了麻烦,因为在静态链接时不应该定义它们。

如果在qcompilerdetection.h中将宏定义为某些内容或为空,则取决于您的环境和/或编译器。

E.g。在Windows环境中,它们的定义如下:

#define Q_DECL_EXPORT __declspec(dllexport)
#define Q_DECL_IMPORT __declspec(dllimport)

如果您想保持代码与多种环境兼容,那么您可以这样做:

在您的标头文件中:

#ifndef TEST_STATIC
#if defined TEST
#define TEST_COMMON_DLLSPEC Q_DECL_EXPORT
#else
#define TEST_COMMON_DLLSPEC Q_DECL_IMPORT
#endif
#else
#define TEST_COMMON_DLLSPEC
#endif


class TEST_COMMON_DLLSPEC Widget : public QWidget
{
};

静态dll pro和app与静态dll的链接:

DEFINES += TEST_STATIC
  • TEST_COMMON_DLLSPEC展开为空

动态dll专业版:

DEFINES += TEST
  • TEST_COMMON_DLLSPEC扩展为Q_DECL_EXPORT

app与动态dll链接:

  • TEST_COMMON_DLLSPEC扩展为Q_DECL_IMPORT