如何在qt中链接dll

时间:2017-01-09 16:06:08

标签: c++ qt dll shared-libraries

我在.dll和.lib都有一个外部库,我有.h文件 库名是'MTK_288_K001'[。dll | .lib | .h]

这是我的qt.pro:

QT += core gui serialport

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++14 static staticlib

TARGET = kiosk

TEMPLATE = app

SOURCES += main.cpp \
    mainwindow.cpp \
    serialport.cpp

RESOURCES += resources.qrc

win32: RC_ICONS = icon.ico

FORMS += mainwindow.ui

HEADERS += mainwindow.h \
    serialport.h

win32 {
    LIBS += -lMTK_288_K001
    LIBS += -L$$PWD/ -lMTK_288_K001
}

INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD

win32:!win32-g++: PRE_TARGETDEPS += $$PWD/MTK_288_K001.lib
else:win32-g++: PRE_TARGETDEPS += $$PWD/MTK_288_K001.lib

的main.cpp

#include <QApplication>
#include "mainwindow.h"

#include "MTK_288_K001.h"

int main(int argc, char *argv[])
{
    MTK288KROpen("COM1");

    qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1");
    QCoreApplication::addLibraryPath("./plugins");
    QApplication a(argc, argv);
    MainWindow mw;
    mw.show();

    return a.exec();
}

MTK_288_K001.h

#define Bad_CommOpen -101
#define Bad_CommClose -105

#define OK                  0
#define ERR                 -1

#define Parameter_Error     -2
#define UpLoadErrorData     -3
#define UpLoadTimeOut       -4 
#define UpLoadCancel        -5 

#include <windows.h>

int APIENTRY GetSysVerion(char *strVerion);
HANDLE APIENTRY MTK288KUOpen();
int APIENTRY MTK288KUClose(HANDLE ComHandle);

int APIENTRY MTK288KUMultOpen(HANDLE DeviceHdlData[],int *DeviceNumbers);
int APIENTRY MTK288KUMultClose(HANDLE DeviceHdlData[],int DeviceNumbers);

int APIENTRY GetDeviceCapabilities(HANDLE ComHandle, int *_InputReportByteLength, int *_OutputReportByteLength);
int APIENTRY ReadACKReport(HANDLE ComHandle,  BYTE _ReportData[],BYTE _ReportLen);
int APIENTRY ReadUpReport(HANDLE ComHandle,  BYTE _ReportData[],BYTE _ReportLen);
int APIENTRY ReadReport(HANDLE ComHandle,  BYTE _ReportData[],BYTE _ReportLen);

int APIENTRY WriteReport(HANDLE ComHandle,  BYTE _ReportData[],BYTE _ReportLen);
int APIENTRY USB_ExeCommand(HANDLE ComHandle,BYTE TxCmCode,BYTE TxPmCode,int TxDataLen,BYTE TxData[],BYTE *RxReplyType,BYTE *RxStCode1,BYTE *RxStCode0,int *RxDataLen,BYTE RxData[]);


HANDLE APIENTRY MTK288KROpen(char *Port);
HANDLE APIENTRY MTK288KROpenWithBaut(char *Port, unsigned int Baudrate);
int APIENTRY MTK288KRClose(HANDLE ComHandle);
int APIENTRY RS232_ExeCommand(HANDLE ComHandle,BYTE TxCmCode,BYTE TxPmCode,int TxDataLen,BYTE TxData[],BYTE *RxReplyType,BYTE *RxStCode1,BYTE *RxStCode0,int *RxDataLen,BYTE RxData[]);


int APIENTRY USB_UpTrackData(HANDLE ComHandle,BYTE tracks,BYTE ReadMode,BYTE _WaitTime,BYTE *RxReplyType,int *_CardDataLen,BYTE _CardData[]);
int APIENTRY USB_Cancel_UpTrackData(HANDLE ComHandle);

int APIENTRY RS232_UpTrackData(HANDLE ComHandle,BYTE tracks,BYTE ReadMode,BYTE _WaitTime,BYTE *RxReplyType,int *_CardDataLen,BYTE _CardData[]);
int APIENTRY RS232_Cancel_UpTrackData(HANDLE ComHandle);

当我构建项目时,qt给了我:

D:\kiosk\main.cpp:-1: error: undefined reference to `MTK288KROpen(char*)@4'

如何告诉qt在外部库中找到此函数?

1 个答案:

答案 0 :(得分:0)

根据您的评论,您的DLL中定义了符号MTK288KROpen。 然而,链接器抱怨MTK288KROpen(char*)@4未定义。

这很可能是因为“坏”而引起的。声明HANDLE APIENTRY MTK288KROpen(char *Port)函数。

正如我在评论中所说,添加extern "C"应该通过让链接器查找MTK288KROpen符号而不是MTK288KROpen(char*)@4来解决问题。

我怀疑我之前在评论中添加extern "C" { }#include "MTK_288_K001.h"周围添加的建议无效,因为您已在MTK_288_K001.h中添加了mainwindow.h

请务必在extern "C"中的MTK288KROpen声明中添加MTK_288_K001.h,如下所示:

...
// This is C++ code so you cannot compile MTK_288_K001.dll anymore with this change, but it should work with your Qt app
extern "C" HANDLE APIENTRY MTK288KROpen(char *Port);
HANDLE APIENTRY MTK288KROpenWithBaut(char *Port, unsigned int Baudrate);
...

链接器不应该再抱怨MTK288KROpen,但可能仍会抱怨其他功能。

如果您仍然有MTK288KROpen的错误,请告诉我它是否是新的错误,以便我可以相应地更新我的答案。并且还要说明APIENTRY的价值是什么。

如果有效,您有2个选项,具体取决于您是否可以修改MTK_288_K001.h

如果您可以编辑它,请像这样添加extern "C"

#ifdef __cplusplus
extern "C" {
#endif

[...]

#ifdef __cplusplus
}
#endif

如果不能,请创建一个中间文件MTK_288_K001_CPP.h并在Qt项目中使用它而不是MTK_288_K001.h

extern "C"
{
#include "MTK_288_K001.h"
}