Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Linking against DLL and calling function in DLL at run-time
QtWS25 Last Chance

Linking against DLL and calling function in DLL at run-time

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 5 Posters 5.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K kahlenberg
    5 Mar 2018, 13:34

    Hi,
    There are lots of topics about linking DLLs but I couldn't find proper answer to my question. Maybe I am missing something.
    So, in order to link to a external, 3rd party library there are some ways according to my understanding:

    1. Static linking at compile-time. Either with wizard in QtCreator or manually add or extend INCLUDEPATH, LIBS variables in .pro file. Include header file of DLL in source code and call functions.
    2. Dynamic linking at run-time (which I want). Using QLibrary, load the DLL from a valid path and include header file of DLL in source code. Get functions in DLL (one-by-one?) with resolve function of QLibrary (Sort of wrapping).

    Is this correct?

    I have a USB chip ( MCP2221) from Microchip and want to use in Qt project. They provide DLL and LIB files and header file.
    How can I load library at run-time. I think I don't need to change my .pro file since it will not be static linking.
    How can I use this function?

    //mcp2221_dll_um.h
    int Mcp2221_GetLibraryVersion(wchar_t* version);
    

    I try to make exactly same thing in the end of this page https://wiki.qt.io/How_to_link_to_a_dll . But important information is missing.
    Thanks.

    A Offline
    A Offline
    aha_1980
    Lifetime Qt Champion
    wrote on 5 Mar 2018, 20:13 last edited by
    #2

    Hi @kahlenberg

    as you said you want to load the library at runtime, have a look at the QLibrary documentation page.

    I've adopted the example from there a bit, so for your case it could look like this:

    QLibrary myLib("mcp2221");
    
    typedef int (*fp_Mcp2221_GetLibraryVersion)(wchar_t*);
    
    fp_Mcp2221_GetLibraryVersion myFunction = 
      (fp_Mcp2221_GetLibraryVersion)
      myLib.resolve("Mcp2221_GetLibraryVersion");
    
    if (Mcp2221_GetLibraryVersion) {
        int result = Mcp2221_GetLibraryVersion("whatever");
    }
    

    Disclaimer: I've not tested this.

    Qt has to stay free or it will die.

    K 1 Reply Last reply 6 Mar 2018, 09:06
    2
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 5 Mar 2018, 20:17 last edited by
      #3

      Hi,

      1. For static linking, you need static libraries. Since you have a .dll, you have a shared library.
      2. That's rather dynamic loading, there's not linking done

      Out of curiosity, since you have both the .lib file and header, why not link to the library directly ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      2
      • A aha_1980
        5 Mar 2018, 20:13

        Hi @kahlenberg

        as you said you want to load the library at runtime, have a look at the QLibrary documentation page.

        I've adopted the example from there a bit, so for your case it could look like this:

        QLibrary myLib("mcp2221");
        
        typedef int (*fp_Mcp2221_GetLibraryVersion)(wchar_t*);
        
        fp_Mcp2221_GetLibraryVersion myFunction = 
          (fp_Mcp2221_GetLibraryVersion)
          myLib.resolve("Mcp2221_GetLibraryVersion");
        
        if (Mcp2221_GetLibraryVersion) {
            int result = Mcp2221_GetLibraryVersion("whatever");
        }
        

        Disclaimer: I've not tested this.

        K Offline
        K Offline
        kahlenberg
        wrote on 6 Mar 2018, 09:06 last edited by
        #4

        @aha_1980
        That is what I am exactly doing, but I get error. Here is my code:

            typedef int (__stdcall *Fp_GetLibraryVersion)(wchar_t *); // with or without __stdcall
        	
        	if(QLibrary::isLibrary(MCP2221LibPath)) { // a valid path
                MCP2221Lib.setFileName(MCP2221LibPath); 
                MCP2221Lib.load();
                if(MCP2221Lib.isLoaded())
                {
                    wchar_t *libver;
                    QString libVersion;
        
                    Fp_GetLibraryVersion Resolved_GetLibraryVersion = (Fp_GetLibraryVersion) MCP2221Lib.resolve(QString("Mcp2221_GetLibraryVersion").toLatin1().data()); // with or without toLatin1().data()
                    qDebug() << MCP2221Lib.errorString(); // Error string comes from here
        
                    if (Resolved_GetLibraryVersion)
                    {
                        qDebug() << Resolved_GetLibraryVersion(libver);
        
                        libVersion = QString::fromWCharArray(libver);
                        qDebug() << libVersion;
                    }
                }
                else
                    qDebug() << "Error " << MCP2221Lib.errorString() << "\n";
            } else
                qDebug() << "Not a library\n";
        

        I am getting:

        Cannot resolve symbol "Mcp2221_GetLibraryVersion" in C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x86.dll: The specified procedure could not be found.
        

        @SGaist
        I just want to try whether or not it is possible, but I think I will link it at compile-time.

        J 1 Reply Last reply 6 Mar 2018, 09:12
        0
        • K kahlenberg
          6 Mar 2018, 09:06

          @aha_1980
          That is what I am exactly doing, but I get error. Here is my code:

              typedef int (__stdcall *Fp_GetLibraryVersion)(wchar_t *); // with or without __stdcall
          	
          	if(QLibrary::isLibrary(MCP2221LibPath)) { // a valid path
                  MCP2221Lib.setFileName(MCP2221LibPath); 
                  MCP2221Lib.load();
                  if(MCP2221Lib.isLoaded())
                  {
                      wchar_t *libver;
                      QString libVersion;
          
                      Fp_GetLibraryVersion Resolved_GetLibraryVersion = (Fp_GetLibraryVersion) MCP2221Lib.resolve(QString("Mcp2221_GetLibraryVersion").toLatin1().data()); // with or without toLatin1().data()
                      qDebug() << MCP2221Lib.errorString(); // Error string comes from here
          
                      if (Resolved_GetLibraryVersion)
                      {
                          qDebug() << Resolved_GetLibraryVersion(libver);
          
                          libVersion = QString::fromWCharArray(libver);
                          qDebug() << libVersion;
                      }
                  }
                  else
                      qDebug() << "Error " << MCP2221Lib.errorString() << "\n";
              } else
                  qDebug() << "Not a library\n";
          

          I am getting:

          Cannot resolve symbol "Mcp2221_GetLibraryVersion" in C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x86.dll: The specified procedure could not be found.
          

          @SGaist
          I just want to try whether or not it is possible, but I think I will link it at compile-time.

          J Offline
          J Offline
          JonB
          wrote on 6 Mar 2018, 09:12 last edited by
          #5

          @kahlenberg said in Linking against DLL and calling function in DLL at run-time:

          Mcp2221_GetLibraryVersion

          One thing: is Mcp2221_GetLibraryVersion actually exported by your library file? What is its export signature?

          K 1 Reply Last reply 6 Mar 2018, 10:22
          0
          • A Offline
            A Offline
            aha_1980
            Lifetime Qt Champion
            wrote on 6 Mar 2018, 09:19 last edited by
            #6

            @kahlenberg said in Linking against DLL and calling function in DLL at run-time:

            I just want to try whether or not it is possible, but I think I will link it at compile-time.

            I'd say either both variants work or none of them.

            Is your program 32 bit too as the library seems to be 32 bit?

            Qt has to stay free or it will die.

            1 Reply Last reply
            0
            • J JonB
              6 Mar 2018, 09:12

              @kahlenberg said in Linking against DLL and calling function in DLL at run-time:

              Mcp2221_GetLibraryVersion

              One thing: is Mcp2221_GetLibraryVersion actually exported by your library file? What is its export signature?

              K Offline
              K Offline
              kahlenberg
              wrote on 6 Mar 2018, 10:22 last edited by
              #7

              @JonB
              This is the header file of library:

              #ifdef __cplusplus
              extern "C"{
              #endif
              
              
                  //for projects importing the .lib, use the MCP2221_LIB preprocessor definition
              #ifndef MCP2221_LIB
              	#ifdef MCP2221_DLL_UM_EXPORTS
              		#define MCP2221_DLL_UM_API __declspec(dllexport)
              	#else
              		#define MCP2221_DLL_UM_API __declspec(dllimport)
              	#endif
              #else 
              	#define MCP2221_DLL_UM_API
              #endif
              
              #define CALLING_CONVENTION __stdcall
              //...
              MCP2221_DLL_UM_API int CALLING_CONVENTION Mcp2221_GetLibraryVersion(wchar_t *version);
              //...
              #ifdef __cplusplus
              }
              #endif
              

              @aha_1980
              Both variants are not working. I also tried to link as static, it gives linker error "undefined reference to `_imp__Mcp2221_GetLibraryVersion@4'". I am using MinGW_5.3.0 32 bit and library is also 32 bit.

              I created a console application as test project and added library via wizard.
              Right-click on project->Add Library->External Library->Linkage:Static, uncheck "Add d suffix for debug version->Finish.

              Here is .pro file:

              QT -= gui
              
              CONFIG += c++11 console
              CONFIG -= app_bundle
              
              # The following define makes your compiler emit warnings if you use
              # any feature of Qt which as been marked deprecated (the exact warnings
              # depend on your compiler). Please consult the documentation of the
              # deprecated API in order to know how to port your code away from it.
              DEFINES += QT_DEPRECATED_WARNINGS
              
              # You can also make your code fail to compile if you use deprecated APIs.
              # In order to do so, uncomment the following line.
              # You can also select to disable deprecated APIs only up to a certain version of Qt.
              #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
              
              SOURCES += main.cpp
              
              unix|win32: LIBS += -L$$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/' -lmcp2221_dll_um_x86
              
              INCLUDEPATH += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib'
              DEPENDPATH += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib'
              
              win32:!win32-g++: PRE_TARGETDEPS += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/mcp2221_dll_um_x86.lib'
              else:unix|win32-g++: PRE_TARGETDEPS += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/libmcp2221_dll_um_x86.a'
              

              First try to build, I am getting linker error:

              :-1: error: No rule to make target 'C:/Projects/SW/libraryTest/../test/MCP2221_DLL(v2.2)/unmanaged/lib/libmcp2221_dll_um_x86.a', needed by 'debug\libraryTest.exe'.  Stop.
              

              I don't have an libmcp2221_dll_um_x86.a file. Here is the directory structure:

              C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll
              C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um.h
              C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x64.dll
              C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x64.lib
              C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x86.dll
              C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x86.lib
              C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib
              C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib\mcp2221_dll_um.h
              C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib\mcp2221_dll_um_x64.lib
              C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib\mcp2221_dll_um_x86.lib
              

              When I delete the line in .pro file

              else:unix|win32-g++: PRE_TARGETDEPS += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/libmcp2221_dll_um_x86.a'
              

              ..and try to build, I get linker error:

              C:\Projects\SW\libraryTest\main.cpp:9: error: undefined reference to `_imp__Mcp2221_GetLibraryVersion@4'
              

              Here is the main.cpp file:

              #include <QCoreApplication>
              #include <QDebug>
              #include "mcp2221_dll_um.h"
              
              int main(int argc, char *argv[])
              {
                  wchar_t libver[100];
                  QCoreApplication a(argc, argv);
                  qDebug() << Mcp2221_GetLibraryVersion(libver);
              
                  return a.exec();
              }
              
              A J J 3 Replies Last reply 6 Mar 2018, 10:37
              0
              • K kahlenberg
                6 Mar 2018, 10:22

                @JonB
                This is the header file of library:

                #ifdef __cplusplus
                extern "C"{
                #endif
                
                
                    //for projects importing the .lib, use the MCP2221_LIB preprocessor definition
                #ifndef MCP2221_LIB
                	#ifdef MCP2221_DLL_UM_EXPORTS
                		#define MCP2221_DLL_UM_API __declspec(dllexport)
                	#else
                		#define MCP2221_DLL_UM_API __declspec(dllimport)
                	#endif
                #else 
                	#define MCP2221_DLL_UM_API
                #endif
                
                #define CALLING_CONVENTION __stdcall
                //...
                MCP2221_DLL_UM_API int CALLING_CONVENTION Mcp2221_GetLibraryVersion(wchar_t *version);
                //...
                #ifdef __cplusplus
                }
                #endif
                

                @aha_1980
                Both variants are not working. I also tried to link as static, it gives linker error "undefined reference to `_imp__Mcp2221_GetLibraryVersion@4'". I am using MinGW_5.3.0 32 bit and library is also 32 bit.

                I created a console application as test project and added library via wizard.
                Right-click on project->Add Library->External Library->Linkage:Static, uncheck "Add d suffix for debug version->Finish.

                Here is .pro file:

                QT -= gui
                
                CONFIG += c++11 console
                CONFIG -= app_bundle
                
                # The following define makes your compiler emit warnings if you use
                # any feature of Qt which as been marked deprecated (the exact warnings
                # depend on your compiler). Please consult the documentation of the
                # deprecated API in order to know how to port your code away from it.
                DEFINES += QT_DEPRECATED_WARNINGS
                
                # You can also make your code fail to compile if you use deprecated APIs.
                # In order to do so, uncomment the following line.
                # You can also select to disable deprecated APIs only up to a certain version of Qt.
                #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
                
                SOURCES += main.cpp
                
                unix|win32: LIBS += -L$$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/' -lmcp2221_dll_um_x86
                
                INCLUDEPATH += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib'
                DEPENDPATH += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib'
                
                win32:!win32-g++: PRE_TARGETDEPS += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/mcp2221_dll_um_x86.lib'
                else:unix|win32-g++: PRE_TARGETDEPS += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/libmcp2221_dll_um_x86.a'
                

                First try to build, I am getting linker error:

                :-1: error: No rule to make target 'C:/Projects/SW/libraryTest/../test/MCP2221_DLL(v2.2)/unmanaged/lib/libmcp2221_dll_um_x86.a', needed by 'debug\libraryTest.exe'.  Stop.
                

                I don't have an libmcp2221_dll_um_x86.a file. Here is the directory structure:

                C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll
                C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um.h
                C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x64.dll
                C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x64.lib
                C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x86.dll
                C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x86.lib
                C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib
                C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib\mcp2221_dll_um.h
                C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib\mcp2221_dll_um_x64.lib
                C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib\mcp2221_dll_um_x86.lib
                

                When I delete the line in .pro file

                else:unix|win32-g++: PRE_TARGETDEPS += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/libmcp2221_dll_um_x86.a'
                

                ..and try to build, I get linker error:

                C:\Projects\SW\libraryTest\main.cpp:9: error: undefined reference to `_imp__Mcp2221_GetLibraryVersion@4'
                

                Here is the main.cpp file:

                #include <QCoreApplication>
                #include <QDebug>
                #include "mcp2221_dll_um.h"
                
                int main(int argc, char *argv[])
                {
                    wchar_t libver[100];
                    QCoreApplication a(argc, argv);
                    qDebug() << Mcp2221_GetLibraryVersion(libver);
                
                    return a.exec();
                }
                
                A Offline
                A Offline
                aha_1980
                Lifetime Qt Champion
                wrote on 6 Mar 2018, 10:37 last edited by
                #8

                @kahlenberg said in Linking against DLL and calling function in DLL at run-time:

                Both variants are not working. I also tried to link as static, it gives linker error "undefined reference to `_imp__Mcp2221_GetLibraryVersion@4'". I am using MinGW_5.3.0 32 bit and library is also 32 bit.

                You need a linker include file (*.a) for MinGW. In your directory you only have MSVC linker include files. So you can google how to create an linker include file for MinGW or ask the library vendor. Otherwise you will not get any step forward in this direction.

                Nevertheless, loading with QLibrary works independent of the Compiler. If you cannot resolve the function, then either it is not exported, or you got the name wrong or the library is not in a valid format (like 32bit vs. 64bit issue).

                Qt has to stay free or it will die.

                1 Reply Last reply
                1
                • K kahlenberg
                  6 Mar 2018, 10:22

                  @JonB
                  This is the header file of library:

                  #ifdef __cplusplus
                  extern "C"{
                  #endif
                  
                  
                      //for projects importing the .lib, use the MCP2221_LIB preprocessor definition
                  #ifndef MCP2221_LIB
                  	#ifdef MCP2221_DLL_UM_EXPORTS
                  		#define MCP2221_DLL_UM_API __declspec(dllexport)
                  	#else
                  		#define MCP2221_DLL_UM_API __declspec(dllimport)
                  	#endif
                  #else 
                  	#define MCP2221_DLL_UM_API
                  #endif
                  
                  #define CALLING_CONVENTION __stdcall
                  //...
                  MCP2221_DLL_UM_API int CALLING_CONVENTION Mcp2221_GetLibraryVersion(wchar_t *version);
                  //...
                  #ifdef __cplusplus
                  }
                  #endif
                  

                  @aha_1980
                  Both variants are not working. I also tried to link as static, it gives linker error "undefined reference to `_imp__Mcp2221_GetLibraryVersion@4'". I am using MinGW_5.3.0 32 bit and library is also 32 bit.

                  I created a console application as test project and added library via wizard.
                  Right-click on project->Add Library->External Library->Linkage:Static, uncheck "Add d suffix for debug version->Finish.

                  Here is .pro file:

                  QT -= gui
                  
                  CONFIG += c++11 console
                  CONFIG -= app_bundle
                  
                  # The following define makes your compiler emit warnings if you use
                  # any feature of Qt which as been marked deprecated (the exact warnings
                  # depend on your compiler). Please consult the documentation of the
                  # deprecated API in order to know how to port your code away from it.
                  DEFINES += QT_DEPRECATED_WARNINGS
                  
                  # You can also make your code fail to compile if you use deprecated APIs.
                  # In order to do so, uncomment the following line.
                  # You can also select to disable deprecated APIs only up to a certain version of Qt.
                  #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
                  
                  SOURCES += main.cpp
                  
                  unix|win32: LIBS += -L$$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/' -lmcp2221_dll_um_x86
                  
                  INCLUDEPATH += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib'
                  DEPENDPATH += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib'
                  
                  win32:!win32-g++: PRE_TARGETDEPS += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/mcp2221_dll_um_x86.lib'
                  else:unix|win32-g++: PRE_TARGETDEPS += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/libmcp2221_dll_um_x86.a'
                  

                  First try to build, I am getting linker error:

                  :-1: error: No rule to make target 'C:/Projects/SW/libraryTest/../test/MCP2221_DLL(v2.2)/unmanaged/lib/libmcp2221_dll_um_x86.a', needed by 'debug\libraryTest.exe'.  Stop.
                  

                  I don't have an libmcp2221_dll_um_x86.a file. Here is the directory structure:

                  C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll
                  C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um.h
                  C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x64.dll
                  C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x64.lib
                  C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x86.dll
                  C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x86.lib
                  C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib
                  C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib\mcp2221_dll_um.h
                  C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib\mcp2221_dll_um_x64.lib
                  C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib\mcp2221_dll_um_x86.lib
                  

                  When I delete the line in .pro file

                  else:unix|win32-g++: PRE_TARGETDEPS += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/libmcp2221_dll_um_x86.a'
                  

                  ..and try to build, I get linker error:

                  C:\Projects\SW\libraryTest\main.cpp:9: error: undefined reference to `_imp__Mcp2221_GetLibraryVersion@4'
                  

                  Here is the main.cpp file:

                  #include <QCoreApplication>
                  #include <QDebug>
                  #include "mcp2221_dll_um.h"
                  
                  int main(int argc, char *argv[])
                  {
                      wchar_t libver[100];
                      QCoreApplication a(argc, argv);
                      qDebug() << Mcp2221_GetLibraryVersion(libver);
                  
                      return a.exec();
                  }
                  
                  J Offline
                  J Offline
                  JonB
                  wrote on 6 Mar 2018, 10:42 last edited by JonB 3 Jun 2018, 10:44
                  #9

                  @kahlenberg said in Linking against DLL and calling function in DLL at run-time:

                  //for projects importing the .lib, use the MCP2221_LIB preprocessor definition
                  

                  #ifndef MCP2221_LIB
                  #ifdef MCP2221_DLL_UM_EXPORTS
                  #define MCP2221_DLL_UM_API __declspec(dllexport)
                  ...
                  MCP2221_DLL_UM_API int CALLING_CONVENTION Mcp2221_GetLibraryVersion(wchar_t *version);

                  I think you ought just make sure your compilation (when you compiled that DLL) is following this __declspec(dllexport) route, else you'll get nowhere?

                  1 Reply Last reply
                  0
                  • K kahlenberg
                    6 Mar 2018, 10:22

                    @JonB
                    This is the header file of library:

                    #ifdef __cplusplus
                    extern "C"{
                    #endif
                    
                    
                        //for projects importing the .lib, use the MCP2221_LIB preprocessor definition
                    #ifndef MCP2221_LIB
                    	#ifdef MCP2221_DLL_UM_EXPORTS
                    		#define MCP2221_DLL_UM_API __declspec(dllexport)
                    	#else
                    		#define MCP2221_DLL_UM_API __declspec(dllimport)
                    	#endif
                    #else 
                    	#define MCP2221_DLL_UM_API
                    #endif
                    
                    #define CALLING_CONVENTION __stdcall
                    //...
                    MCP2221_DLL_UM_API int CALLING_CONVENTION Mcp2221_GetLibraryVersion(wchar_t *version);
                    //...
                    #ifdef __cplusplus
                    }
                    #endif
                    

                    @aha_1980
                    Both variants are not working. I also tried to link as static, it gives linker error "undefined reference to `_imp__Mcp2221_GetLibraryVersion@4'". I am using MinGW_5.3.0 32 bit and library is also 32 bit.

                    I created a console application as test project and added library via wizard.
                    Right-click on project->Add Library->External Library->Linkage:Static, uncheck "Add d suffix for debug version->Finish.

                    Here is .pro file:

                    QT -= gui
                    
                    CONFIG += c++11 console
                    CONFIG -= app_bundle
                    
                    # The following define makes your compiler emit warnings if you use
                    # any feature of Qt which as been marked deprecated (the exact warnings
                    # depend on your compiler). Please consult the documentation of the
                    # deprecated API in order to know how to port your code away from it.
                    DEFINES += QT_DEPRECATED_WARNINGS
                    
                    # You can also make your code fail to compile if you use deprecated APIs.
                    # In order to do so, uncomment the following line.
                    # You can also select to disable deprecated APIs only up to a certain version of Qt.
                    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
                    
                    SOURCES += main.cpp
                    
                    unix|win32: LIBS += -L$$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/' -lmcp2221_dll_um_x86
                    
                    INCLUDEPATH += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib'
                    DEPENDPATH += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib'
                    
                    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/mcp2221_dll_um_x86.lib'
                    else:unix|win32-g++: PRE_TARGETDEPS += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/libmcp2221_dll_um_x86.a'
                    

                    First try to build, I am getting linker error:

                    :-1: error: No rule to make target 'C:/Projects/SW/libraryTest/../test/MCP2221_DLL(v2.2)/unmanaged/lib/libmcp2221_dll_um_x86.a', needed by 'debug\libraryTest.exe'.  Stop.
                    

                    I don't have an libmcp2221_dll_um_x86.a file. Here is the directory structure:

                    C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll
                    C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um.h
                    C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x64.dll
                    C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x64.lib
                    C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x86.dll
                    C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\dll\mcp2221_dll_um_x86.lib
                    C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib
                    C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib\mcp2221_dll_um.h
                    C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib\mcp2221_dll_um_x64.lib
                    C:\Projects\SW\test\MCP2221_DLL(v2.2)\unmanaged\lib\mcp2221_dll_um_x86.lib
                    

                    When I delete the line in .pro file

                    else:unix|win32-g++: PRE_TARGETDEPS += $$PWD/'../test/MCP2221_DLL(v2.2)/unmanaged/lib/libmcp2221_dll_um_x86.a'
                    

                    ..and try to build, I get linker error:

                    C:\Projects\SW\libraryTest\main.cpp:9: error: undefined reference to `_imp__Mcp2221_GetLibraryVersion@4'
                    

                    Here is the main.cpp file:

                    #include <QCoreApplication>
                    #include <QDebug>
                    #include "mcp2221_dll_um.h"
                    
                    int main(int argc, char *argv[])
                    {
                        wchar_t libver[100];
                        QCoreApplication a(argc, argv);
                        qDebug() << Mcp2221_GetLibraryVersion(libver);
                    
                        return a.exec();
                    }
                    
                    J Offline
                    J Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on 6 Mar 2018, 11:44 last edited by
                    #10

                    @kahlenberg Is the DLL built using same compiler?

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • K Offline
                      K Offline
                      kahlenberg
                      wrote on 6 Mar 2018, 12:16 last edited by
                      #11

                      I solved the problem. The problem was, I was using wrong library file :). I used library file (.lib) in dll/ directory not in lib/ directory. It worked. Maybe I can update wiki at the end of https://wiki.qt.io/How_to_link_to_a_dll .

                      @jsulm No, I downloded them from microchip website.

                      Thanks for all answers.

                      1 Reply Last reply
                      0

                      11/11

                      6 Mar 2018, 12:16

                      • Login

                      • Login or register to search.
                      11 out of 11
                      • First post
                        11/11
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved