A little help linking with a library...



  • Hi All,

    I'm trying to figure out what is wrong. I'm using Qt 5.5.1 with Visual Studio 2013 32bit.

    A popular vendor of IP serial devices is Moxa (www.moxa.com). They provide a free admin suite to control the devices in addition they have a .h, .lib, and .dll to talk to the devices.

    In side of their .h they surround the function names with extern "C":

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    // Server Control
    int NSWINAPI nsio_init();
    int NSWINAPI nsio_end();
    

    NSWINAPI is defined as nothing. So the function definitions should be: int nsio_init();

    Using dumpbin.exe on the library file gives the following public symbols:

        61 public symbols
    
          BE2 __IMPORT_DESCRIPTOR_IPSerial
          E12 __NULL_IMPORT_DESCRIPTOR
          F4A IPSerial_NULL_THUNK_DATA
         1716 __imp__nsio_init@0
         1716 _nsio_init@0
         15D2 __imp__nsio_end@0
         15D2 _nsio_end@0
    

    Obviously I won't bore you all with all 61 symbols! :-)

    Anyway as you can see at 1716 is _nsio_init. Yet the h file defines it as int nsio_init(). I'm puzzled if this is normal?

    In my .pro file I link to the libraries as follows:

    win32: LIBS += -L$$PWD/libs/ -lIPSerial -lftd2xx
    
    INCLUDEPATH += $$PWD/libs
    DEPENDPATH += $$PWD/libs
    
    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/libs/ftd2xx.lib $$PWD/libs/IPSerial.lib
    

    As a side note you can see I link with ftd2xx.lib. That linking works fine and function calls are resolved. It looks the same when dumped:

    185 public symbols
    
         28DE __IMPORT_DESCRIPTOR_FTD2XX
         2B04 __NULL_IMPORT_DESCRIPTOR
         2C3A FTD2XX_NULL_THUNK_DATA
         3CAC _FT_Open@8
         3CAC __imp__FT_Open@8
         2D8A _FT_Close@4
         2D8A __imp__FT_Close@4
    

    So I'm guessing the underscores are expected.

    The issue is after running qmake and rebuilding I get:

    io_serialiodevice.obj:-1: error: LNK2019: unresolved external symbol _nsio_init referenced in function "public: bool __thiscall io_serialIODevice::setSerialDevice(class QString &)" (?setSerialDevice@io_serialIODevice@@QAE_NAAVQString@@@Z)
    

    I fiddled around abit and added

    #ifndef NSWINAPI
    #define NSWINAPI __declspec(dllimport)
    #endif
    

    Since the ftd2xx.h file does so for its library and now I get:

    io_serialiodevice.obj:-1: error: LNK2019: unresolved external symbol __imp__nsio_init referenced in function "public: bool __thiscall io_serialIODevice::setSerialDevice(class QString &)" (?setSerialDevice@io_serialIODevice@@QAE_NAAVQString@@@Z)
    

    While this seems closer in comparison to the ftd2xx if I remove that lib I see this:

    io_serialiodevice.obj:-1: error: LNK2019: unresolved external symbol __imp__FT_OpenEx@12 referenced in function "public: bool __thiscall io_serialIODevice::open(class QFlags<enum QIODevice::OpenModeFlag>)" (?open@io_serialIODevice@@QAE_NV?$QFlags@W4OpenModeFlag@QIODevice@@@@@Z)
    

    So the import here as the @12 reference whereas the one for IPSerial does not.

    I'm just wondering if I'm missing something simple. I know what the DLL function calls look like as I've used them from C# so I might try just creating my own lib but I'm hoping to avoid that task.

    Any help or insight would be appreciated.


  • Qt Champions 2016

    Hi
    Maybe stupid questions, the lib and DLL file is made for 2013 32bit. ?
    The @ and numbers is called name mangling as you probably know.

    With c++ the LIB and DLL must be compiled with exact same version of visual studio, else it wont work.
    (as far as i know)



  • Hi mrjj,

    Thanks for the reply. The library is 32 bit and yes on the name mangling. I get that and hence the extern "C" stuff.

    I don't believe you are entirely correct on the same version of Visual Studio stuff. I could be wrong but for example this same library can be linked and used with a Delphi 32 program versions 7 through 2010. Also the DLL has sample code to import into C# and that works just fine too but I think the C# import bypasses the .lib. I'm beginning to wonder if the .lib is somehow faulty.

    I have a query in with Moxa to see what they say.


  • Qt Champions 2016

    Hi
    Well now u mention it, i have also used DLLS with delphi :)
    In old times, with visual C++ , one could create a lib file from a DLL.
    https://adrianhenke.wordpress.com/2008/12/05/create-lib-file-from-dll/
    I wonder if that is still possible in 2015 ?


  • Qt Champions 2016

    @SysTech
    Hello,
    If I get this right you're using DLLs, correct?

    win32:!win32-g++: PRE_TARGETDEPS += $PWD/libs/ftd2xx.lib $PWD/libs/IPSerial.lib
    

    Then why this line in the .pro file? If memory serves me, you should do that only if you want to link statically, which would not be true in your case. As you've correctly noted, a C-linkage function should not be dependent on the compiler used, since the symbols don't have name decorations. Maybe try to comment the PRE_TARGETDEPS in your project file, and try a full rebuild?

    Kind regards.



  • @kshegunov

    It seems if I remove that line that it cannot find the libs to link. I could be wrong.

    I copied that line from another project that is working with the ftd2xx and some other libs. It seems this IPSerial.lib is the problem.

    I will give it a try! Thanks!


  • Qt Champions 2016

    @SysTech
    Hello,
    It's been a long time since I've actually used windows, but try to set the paths properly and I think it should work. On linux symbols are resolved at runtime and information is kept in the ELF header, so here we don't have .lib files (which is not always the better way, though). I believe on windows you only need to properly setup the .lib files' paths and names for the -l and -L switches to work.

    Kind regards.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.