LNK2019 error: How to import and use ftd2xx.lib in QT app
-
I would like to import ftd2xx.lib 64bit library to my QT app in order to control GPIO pins on Adafruit FT232H chip. Got the lib from the official site (Win 64bit version). Made small test app but for any function from the lib got the LNK2019 error:
mainwindow.obj:-1: error: LNK2019: unresolved external symbol __imp_FT_Open referenced in function "public: __cdecl MainWindow::MainWindow(class QWidget *)" (??0MainWindow@@QEAA@PEAVQWidget@@@Z) mainwindow.obj:-1: error: LNK2019: unresolved external symbol __imp_FT_CreateDeviceInfoList referenced in function "public: __cdecl MainWindow::MainWindow(class QWidget *)" (??0MainWindow@@QEAA@PEAVQWidget@@@Z)
Any hint? Thanks in advance.
.pro file:
QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 compile_included_sources # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ inc/stdafx.cpp \ main.cpp \ mainwindow.cpp HEADERS += \ inc/ftd2xx.h \ inc/stdafx.h \ inc/targetver.h \ mainwindow.h FORMS += \ mainwindow.ui DISTFILES += \ inc/ftd2xx.lib # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target win32:CONFIG(release, debug|release): LIBS += -L$$PWD/inc/ -lftd2xx else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/inc/ -lftd2xx INCLUDEPATH += $$PWD/inc DEPENDPATH += $$PWD/inc LIBS += -L$$PWD/inc -lftd2xx #win32:LIBS += C:\Workarea\QtC_projects\Adafruit_ftd2xx_GPIO\inc\ftd2xx.lib #win32:LIBS += -L"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x64" -lUser32 #win32:LIBS += -L"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x86" -lUser32 win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/inc/libftd2xx.a else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/inc/libftd2xx.a else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/inc/ftd2xx.lib else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/inc/ftd2xx.lib
mainwindow.h file:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <Windows.h> #include "stdafx.h" #include "ftd2xx.h" #include <stdlib.h> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_pushButton_clicked(); void on_pushButton_2_clicked(); void on_pushButton_3_clicked(); private: Ui::MainWindow *ui; FT_STATUS ftStatus; // Status FT_HANDLE ftHandle; // Port DWORD dwNumDevs; // The number of devices unsigned int uiDevIndex = 0xF; // The device in the list that we'll use BYTE OutputBuffer[16]; //Buffer to hold MPSSE commands BYTE InputBuffer[16]; //Buffer to hold read bytes DWORD dwClockDivisor = 0x05DB; //1MHz DWORD dwCount = 0; // General loop index DWORD dwNumBytesToSend = 0; // Index to the output buffer DWORD dwNumBytesSent = 0; // Bytes sent - used with FT_Write DWORD dwNumBytesToRead = 0; // Number of bytes available to read in the driver's input buffer DWORD dwNumBytesRead = 0; // Count of bytes read - used with FT_Read bool SendByteTurnOn(); bool SendByteTurnOff(); }; #endif // MAINWINDOW_H
mainwindow.cpp file:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QLibrary> #include <QDebug> #include <Windows.h> #include <stdio.h> #include "stdafx.h" #include "ftd2xx.h" //#pragma comment(lib, "FTD2XX.lib") MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); QLibrary library("ftd2xx.lib"); if(!library.load()) qDebug() << library.errorString(); if(library.load()) qDebug() << "library loaded"; // Check if an FTDI device exist? printf("Checking for FTDI devices...\n"); ftStatus = FT_CreateDeviceInfoList(&dwNumDevs); // Get the number of FTDI devices if (ftStatus != FT_OK) // Did the command execute OK? { printf("Error in getting the number of devices\n"); } if (dwNumDevs < 1) // Exit if we don't see any { printf("There are no FTDI devices installed\n"); } printf("%d FTDI devices found\n", dwNumDevs); ftStatus = FT_Open(0, &ftHandle); if (ftStatus != FT_OK) { printf("Open Failed with error %d\n", ftStatus); } } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { } void MainWindow::on_pushButton_2_clicked() { } void MainWindow::on_pushButton_3_clicked() { } bool MainWindow::SendByteTurnOn() { OutputBuffer[dwNumBytesToSend++] = '\x82'; OutputBuffer[dwNumBytesToSend++] = '\x49'; OutputBuffer[dwNumBytesToSend++] = '\x49'; return TRUE; } bool MainWindow::SendByteTurnOff() { OutputBuffer[dwNumBytesToSend++] = '\x82'; OutputBuffer[dwNumBytesToSend++] = '\x00'; OutputBuffer[dwNumBytesToSend++] = '\x49'; return TRUE; }
main.cpp file:
#include "mainwindow.h" #include "ftd2xx.h" #include "stdafx.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
-
@Laki said in LNK2019 error: How to import and use ftd2xx.lib in QT app:
LIBS += -L$$PWD/inc/ -lftd2xx
Is that lib in that folder?
Also check the linker call (post it here).
Keep in mind that with C++ you can't mix different compilers in same application. So, if this lib was built using incompatible compiler it will not work. -
Is that lib in that folder?
Yes, it is. I tried to move this lib and compile failed due to "no such file..."
Also check the linker call (post it here).
link /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:WINDOWS "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /MANIFEST:embed /OUT:debug\Adafruit_ftd2xx_GPIO.exe @C:\Users\XX\AppData\Local\Temp\Adafruit_ftd2xx_GPIO.exe.31124.2297.jom mainwindow.obj : error LNK2019: unresolved external symbol __imp_FT_Open referenced in function "public: __cdecl MainWindow::MainWindow(class QWidget *)" (??0MainWindow@@QEAA@PEAVQWidget@@@Z) mainwindow.obj : error LNK2019: unresolved external symbol __imp_FT_CreateDeviceInfoList referenced in function "public: __cdecl MainWindow::MainWindow(class QWidget *)" (??0MainWindow@@QEAA@PEAVQWidget@@@Z) debug\Adafruit_ftd2xx_GPIO.exe : fatal error LNK1120: 2 unresolved externals jom: C:\Workarea\QtC_projects\build-Adafruit_ftd2xx_GPIO-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug\Makefile.Debug [debug\Adafruit_ftd2xx_GPIO.exe] Error 1120 jom: C:\Workarea\QtC_projects\build-Adafruit_ftd2xx_GPIO-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug\Makefile [debug] Error 2 16:28:13: The process "C:\Qt\Tools\QtCreator\bin\jom\jom.exe" exited with code 2. Error while building/deploying project Adafruit_ftd2xx_GPIO (kit: Desktop Qt 5.15.2 MSVC2019 64bit) When executing step "Make"
Keep in mind that with C++ you can't mix different compilers in same application. So, if this lib was built using incompatible compiler it will not work.
Probably that is the case, because this lib (but 32bit version) works in Visual Studio :(
-
Hi,
Are you sure you are pointing the linker to the 64bit version of libftd2xx ?
-
You can use dumpbin on the command line to check what your library is made of.
-
I've never used that library, but according to the docs the structure of it is like so:
ftd2xx.h — C/C++ header file Dynamic library: ftd2xx.lib for 32-bit systems in folder i386 ftd2xx.dll for 32-bit systems in folder i386 ftd2xx.lib for 64-bit systems in folder amd64 ftd2xx.dll for 64-bit systems in folder amd64 Static library: ftd2xx.lib for 32-bit systems in folder Static\i386 ftd2xx.lib for 64-bit systems in folder Static\amd64
It's a bit weird that you would have a .lib file in an include directory, so you must've copied it there from one of those. Maybe you copied the wrong one? Are you using the static or dynamic linking? The doc also says that you need to define
FTD2XX_STATIC
if you're using the static library. Maybe you copied that one and missing that define? It probably excludes some stuff from the header, like those functions your linker is missing. -
The doc also says that you need to define FTD2XX_STATIC if you're using the static library.
I read this in the documentation, but tried to define into the source code. After you mentioned that I put
DEFINES += FTD2XX_STATIC
into the .pro file and that is works.
Thank you all for help.