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. Failed to resolve symbols (Windows)
Forum Updated to NodeBB v4.3 + New Features

Failed to resolve symbols (Windows)

Scheduled Pinned Locked Moved Unsolved General and Desktop
19 Posts 4 Posters 4.7k Views 1 Watching
  • 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.
  • G Offline
    G Offline
    gav007
    wrote on last edited by
    #1

    I received a Windows shared library ( xxxapi.dll ) that I would like to load at runtime. It is provided with headers (that actually refuse the MinGW compiler if I include them in the code !).
    As an example, one of the functions I would like to use is declared as this in those headers:

    extern "C" long __stdcall xxxInitialize( void );
    

    I attempt to use the following code to load this call:

       QString libName( "xxxapi" );
       if ( !libName.isNull() )
       {
           QLibrary lib( libName );
           if ( lib.load() )
           {
               typedef long __stdcall (*InitFunction)( void );
               InitFunction init = reinterpret_cast<InitFunction>( lib.resolve("xxxInitialize") );
               if ( init )
               {
                   qDebug() << "Found the xxxInitialize function :-)";
                   init();
               }
               else
                   qCritical() << lib.errorString();
           }
           else {
               qCritical() << "Failed to load the " << libName << " library !";
               qCritical() << lib.errorString();
           }
       }
    
    

    The error is always:

    Cannot resolve symbol \"xxxInitialize\" in xxxapi: The specified procedure could not be found.
    

    I'm using Qt 5.12.1 with MinGW 7.3, everything in 64 bits (the DLL also is mentioned x64).

    I probably do something wrong. Could someone give some support ?
    Thanks.

    Regards.

    JonBJ 1 Reply Last reply
    0
    • mrdebugM Offline
      mrdebugM Offline
      mrdebug
      wrote on last edited by
      #2

      I suggest you to use Qt based on mswc.
      This is working for me.

      uintptr_t deImplementation;
      typedef void (*pCreate)(uintptr_t *deImplementation);
      pCreate Create;
      Create= (pCreate)Library.resolve("Create");
      Create(&deImplementation);
      
      JonBJ 1 Reply Last reply
      0
      • mrdebugM mrdebug

        I suggest you to use Qt based on mswc.
        This is working for me.

        uintptr_t deImplementation;
        typedef void (*pCreate)(uintptr_t *deImplementation);
        pCreate Create;
        Create= (pCreate)Library.resolve("Create");
        Create(&deImplementation);
        
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #3

        @mrdebug
        The OP's error message indicates that it is lib.resolve("xxxInitialize") which is failing to find the specified symbol. How does your solution address that?

        1 Reply Last reply
        0
        • G gav007

          I received a Windows shared library ( xxxapi.dll ) that I would like to load at runtime. It is provided with headers (that actually refuse the MinGW compiler if I include them in the code !).
          As an example, one of the functions I would like to use is declared as this in those headers:

          extern "C" long __stdcall xxxInitialize( void );
          

          I attempt to use the following code to load this call:

             QString libName( "xxxapi" );
             if ( !libName.isNull() )
             {
                 QLibrary lib( libName );
                 if ( lib.load() )
                 {
                     typedef long __stdcall (*InitFunction)( void );
                     InitFunction init = reinterpret_cast<InitFunction>( lib.resolve("xxxInitialize") );
                     if ( init )
                     {
                         qDebug() << "Found the xxxInitialize function :-)";
                         init();
                     }
                     else
                         qCritical() << lib.errorString();
                 }
                 else {
                     qCritical() << "Failed to load the " << libName << " library !";
                     qCritical() << lib.errorString();
                 }
             }
          
          

          The error is always:

          Cannot resolve symbol \"xxxInitialize\" in xxxapi: The specified procedure could not be found.
          

          I'm using Qt 5.12.1 with MinGW 7.3, everything in 64 bits (the DLL also is mentioned x64).

          I probably do something wrong. Could someone give some support ?
          Thanks.

          Regards.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @gav007
          From http://doc.qt.io/qt-5/qlibrary.html#resolve the original needs to have been compiled with __declspec(dllexport). How do you know whether the code (.c/.cpp) did that? Does documentation tell you that xxInitialize has been exported from the DLL for you to use?

          I am wondering whether it could matter if that DLL was compiled with MSVC while you are using MinGW. I don't think so, as Windows calls LoadLibrary() & GetProcAddress() should work regardless of compiler, it's just a niggle if that DLL is not MinGW...

          G 1 Reply Last reply
          4
          • JonBJ JonB

            @gav007
            From http://doc.qt.io/qt-5/qlibrary.html#resolve the original needs to have been compiled with __declspec(dllexport). How do you know whether the code (.c/.cpp) did that? Does documentation tell you that xxInitialize has been exported from the DLL for you to use?

            I am wondering whether it could matter if that DLL was compiled with MSVC while you are using MinGW. I don't think so, as Windows calls LoadLibrary() & GetProcAddress() should work regardless of compiler, it's just a niggle if that DLL is not MinGW...

            G Offline
            G Offline
            gav007
            wrote on last edited by
            #5

            @JonB
            I'm not expert of the Windows environment. And your question is also mine.
            I did not notice any _declspec(dllimport) in the header files. Does it mean that the library has not been compiled with the exporting declaration ? And if not exported, would it work anyway with MSVC ?

            JonBJ 1 Reply Last reply
            0
            • G gav007

              @JonB
              I'm not expert of the Windows environment. And your question is also mine.
              I did not notice any _declspec(dllimport) in the header files. Does it mean that the library has not been compiled with the exporting declaration ? And if not exported, would it work anyway with MSVC ?

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @gav007
              As per the code in the link I gave, I think that the __declspec(dllexport) only has to go against the function definition --- i.e. its code implementation in its C/C++ .c/.cpp source file --- not against the function's declaration in the header .h file you are seeing. You don't have its source code to look at? Also I asked how you know that this function has been suitably marked for export for you to use by its developers? If they have not said you can call it it may (well) not have been designated with the __declspec(dllexport) by them.

              Suggest you Google for windows dll list exported symbols or similar, e.g. https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/ab3cd884-fcb3-442a-9798-62d9ed31c1cb/list-of-exported-functions-of-a-dll?forum=windowssdk. There are various tools you can use to inspect the DLL to see just what it exports, e.g. I think dumpbin /exports file.dll.

              G 1 Reply Last reply
              3
              • JonBJ JonB

                @gav007
                As per the code in the link I gave, I think that the __declspec(dllexport) only has to go against the function definition --- i.e. its code implementation in its C/C++ .c/.cpp source file --- not against the function's declaration in the header .h file you are seeing. You don't have its source code to look at? Also I asked how you know that this function has been suitably marked for export for you to use by its developers? If they have not said you can call it it may (well) not have been designated with the __declspec(dllexport) by them.

                Suggest you Google for windows dll list exported symbols or similar, e.g. https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/ab3cd884-fcb3-442a-9798-62d9ed31c1cb/list-of-exported-functions-of-a-dll?forum=windowssdk. There are various tools you can use to inspect the DLL to see just what it exports, e.g. I think dumpbin /exports file.dll.

                G Offline
                G Offline
                gav007
                wrote on last edited by
                #7

                @JonB
                Nice trick !
                Using dumpbin.exe, I could notice that the export call is XxxInitialize (starting with an upper character), while the header file really mentions the call starting with a lower case character ! I did not know that MSVC could manage this.
                I updated the code above and it worked.
                Many many thanks.

                @mrdebug
                Thanks also for the reaction.

                Best regards.

                1 Reply Last reply
                1
                • G Offline
                  G Offline
                  gav007
                  wrote on last edited by
                  #8

                  Ooops ! Too fast !

                  The exported calls I got with the dumpbin.exe are actually the C++ interface. That's the reason why they starts with an upper case character. And unfortunately, this interface makes use of class interfaces Qt Creator is not able to understand (until now) since many MSVC keywords are used.
                  So how comes that the C calls are not visible ?

                  JonBJ 1 Reply Last reply
                  0
                  • G gav007

                    Ooops ! Too fast !

                    The exported calls I got with the dumpbin.exe are actually the C++ interface. That's the reason why they starts with an upper case character. And unfortunately, this interface makes use of class interfaces Qt Creator is not able to understand (until now) since many MSVC keywords are used.
                    So how comes that the C calls are not visible ?

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #9

                    @gav007
                    This is all a bit outside my pay-grade. But if that shows what has actually been exported, and there simply isn't a plain C one corresponding to your extern "C" long __stdcall xxxInitialize( void );, then that indicates to me that such a symbol is not actually exported. I go back to: how do you know that line in a header file actually corresponds to a function which was DLL-exported by them?

                    P.S.
                    This is way beyond me now, but have a read of https://stackoverflow.com/a/41910450/489865. He's talking about extern "C" in combination with __stdcall. Then again, he may be saying it is not a problem if you are x64 rather than x86... !

                    1 Reply Last reply
                    0
                    • mrdebugM Offline
                      mrdebugM Offline
                      mrdebug
                      wrote on last edited by
                      #10
                      This post is deleted!
                      JonBJ 1 Reply Last reply
                      0
                      • mrdebugM mrdebug

                        This post is deleted!

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by
                        #11

                        @mrdebug
                        But the OP does not have the sources to the DLL he wants, it's third-party. And he can't get the name he believes he wants to import to work. So I really do not mean to be impolite, please don't take it that way, but how is anything you are writing relevant to his situation?

                        1 Reply Last reply
                        0
                        • mrdebugM Offline
                          mrdebugM Offline
                          mrdebug
                          wrote on last edited by
                          #12

                          Ops, sorry

                          JonBJ 1 Reply Last reply
                          0
                          • mrdebugM mrdebug

                            Ops, sorry

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by JonB
                            #13

                            @mrdebug
                            No problem :) While your code would work fine in itself, I think you missed the point that the OP is trying to import against a third-party DLL over which he has no control. He's doing the right stuff to load the library and try to resolve a symbol, like your code, but we're not sure how the DLL was written/compiled/linked.

                            1 Reply Last reply
                            0
                            • G Offline
                              G Offline
                              gav007
                              wrote on last edited by gav007
                              #14

                              Hi, thanks for your reflections.

                              I know that the C calls are usable because the small SDK (intended for MSVC) also provides some sample codes.

                              Other question : for the C++ interface, if I translate the class declarations into a standard that Qt could understand, could it give a chance ? Here is a sample declaration:

                              #define OUT
                              ...
                              #define THIS_
                              ...
                              #define DECLSPEC_NOVTABLE 
                              ...
                              #define __STRUCT__ struct
                              #undef interface
                              #define interface __STRUCT__
                              #define STDMETHOD(method) virtual COM_DECLSPEC_NOTHROW long STDMETHODCALLTYPE method
                              #define DECLARE_INTERFACE_(iface, baseiface) interface DECLSPEC_NOVTABLE iface : public baseiface
                              ...
                              
                              #undef  INTERFACE
                              #define INTERFACE IXxxFifo
                              DECLARE_INTERFACE_(IXxxFifo, IUnknown)
                              {
                                //~~~ IUnknown methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                STDMETHOD(QueryInterface)(THIS_ IN REFIID riid, OUT PVOID *ppv)    PURE;
                                STDMETHOD_(ULONG,AddRef )(THIS)                                    PURE;
                                STDMETHOD_(ULONG,Release)(THIS)                                    PURE;
                                //~~~ IXxxFifo methods  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                STDMETHOD(GetCapacity )(THIS_ OUT PUINT16 pwCapacity)              PURE;
                                STDMETHOD(GetEntrySize)(THIS_ OUT PUINT16 pwSize)                  PURE;
                                STDMETHOD(GetFreeCount)(THIS_ OUT PUINT16 pwCount)                 PURE;
                                STDMETHOD(GetFillCount)(THIS_ OUT PUINT16 pwCount)                 PURE;
                                STDMETHOD(GetFillLevel)(THIS_ OUT PUINT16 pwLevel)                 PURE;
                              };
                              #undef INTERFACE
                              

                              Worth a try ?

                              Regards

                              1 Reply Last reply
                              0
                              • G Offline
                                G Offline
                                gav007
                                wrote on last edited by
                                #15

                                I installed MSVC 2017 Community edition for tests.
                                The C functions cannot be linked as well. The sample codes cannot be compiled.
                                As @JonB stated it, those calls are not exported !

                                I will attempt to use the provided C++ class interfaces, but I'm afraid that something goes wrong at a certain point.

                                Best regards.

                                1 Reply Last reply
                                0
                                • hskoglundH Offline
                                  hskoglundH Offline
                                  hskoglund
                                  wrote on last edited by hskoglund
                                  #16

                                  Hi, that sample declaration above looks like an ancient version of the CAN bus driver, for example see here: http://gitlab.unique-conception.org/qt-can-2.0/qt-can-driver-ixxat/blob/master/VciWindows_4.0/inc/vcisdk.h

                                  Perhaps you have more luck if you try a newer version: https://www.ixxat.com/support/file-and-documents-download/drivers/vci-v4-driver

                                  Edit: anyways as you say, those interfaces are not callable directly with C or C++, you have to use an ancient technology called COM :-(
                                  This is still supported in Qt, through something called ActiveQt, see more here

                                  Edit again: forgot to mention, if indeed you're developing with a CAN bus card, Qt supports the CAN bus as well, see here

                                  G 1 Reply Last reply
                                  0
                                  • hskoglundH hskoglund

                                    Hi, that sample declaration above looks like an ancient version of the CAN bus driver, for example see here: http://gitlab.unique-conception.org/qt-can-2.0/qt-can-driver-ixxat/blob/master/VciWindows_4.0/inc/vcisdk.h

                                    Perhaps you have more luck if you try a newer version: https://www.ixxat.com/support/file-and-documents-download/drivers/vci-v4-driver

                                    Edit: anyways as you say, those interfaces are not callable directly with C or C++, you have to use an ancient technology called COM :-(
                                    This is still supported in Qt, through something called ActiveQt, see more here

                                    Edit again: forgot to mention, if indeed you're developing with a CAN bus card, Qt supports the CAN bus as well, see here

                                    G Offline
                                    G Offline
                                    gav007
                                    wrote on last edited by
                                    #17

                                    @hskoglund
                                    Damn ! I'm discovered. ;-) For an unknown reason, i did not wish to divulge it ;-)

                                    I already used Qt CAN for other projects. In the current case, I have to use the VCI driver (in the version 4) on a Windows platform.
                                    I'm currently in a test phase and I did not decide the way I will use this driver yet.
                                    I attempt to use the C interface to be able to load the library at runtime and also because of the troubles I face when compiling with MinGW.
                                    I already found a plugin implementation here but I could not set it up.
                                    I'm currently checking with MSVC 2017 but this cannot be a solution.

                                    Thanks for the link to ActiveQt. I will check.

                                    Regards.

                                    hskoglundH 1 Reply Last reply
                                    0
                                    • G gav007

                                      @hskoglund
                                      Damn ! I'm discovered. ;-) For an unknown reason, i did not wish to divulge it ;-)

                                      I already used Qt CAN for other projects. In the current case, I have to use the VCI driver (in the version 4) on a Windows platform.
                                      I'm currently in a test phase and I did not decide the way I will use this driver yet.
                                      I attempt to use the C interface to be able to load the library at runtime and also because of the troubles I face when compiling with MinGW.
                                      I already found a plugin implementation here but I could not set it up.
                                      I'm currently checking with MSVC 2017 but this cannot be a solution.

                                      Thanks for the link to ActiveQt. I will check.

                                      Regards.

                                      hskoglundH Offline
                                      hskoglundH Offline
                                      hskoglund
                                      wrote on last edited by
                                      #18

                                      @gav007 There should be plenty of examples on how to call the VCI driver through COM I think. Perhaps you'll be not 100% covered by using ActiveQt and instead have to go native and call COM directly. And doing that is much easier with the MSVC compiler as compared to the MinGW compiler.

                                      1 Reply Last reply
                                      0
                                      • G Offline
                                        G Offline
                                        gav007
                                        wrote on last edited by
                                        #19

                                        So.
                                        It works using MSVC 2017 Community edition, but the result is really unstable. And I cannot get a debugging session (?). One of the reasons may be that I'm unfamiliar with such Windows environment ;-).
                                        Investigation in this way will stop here and we abandon the VCI driver. We will choose a new USB-to-CAN device that can be easily used within a Qt Can plugin implementation (and with MinGW).

                                        Many thanks for your support.
                                        Best regards.

                                        1 Reply Last reply
                                        0

                                        • Login

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