Importing .dll into Qt

2019-01-23 00:03发布

问题:

I want to bring a .dll dependency into my Qt project.

So I added this to my .pro file:

win32 {
LIBS += C:\lib\dependency.lib
LIBS += C:\lib\dependency.dll
}

And then (I don't know if this is the right syntax or not)

#include <windows.h>
Q_DECL_IMPORT int WINAPI DoSomething();

btw the .dll looks something like this:

#include <windows.h>
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, 
                                        LPVOID lpReserved)
{
    return TRUE;
}

extern "C"
{
int WINAPI DoSomething() { return -1; }
};

Getting error: unresolved symbol?

Note: I'm not experienced with .dll's outside of .NET's ez pz assembly architechture, definitely a n00b.

回答1:

Your "LIBS +=" syntax is wrong. Try this:

win32 {
    LIBS += -LC:/lib/ -ldependency
}

I'm also not sure if having absolute paths with drive letter in your .pro file is a good idea - I usually keep the dependencies somewhere in the project tree and use relative path.

EDIT:

I suppose that something is wrong in your dll, i.e. the symbols are not exported correctly. I always use template provided by QtCreator:

  1. Inside dll project there is mydll_global.h header with code like that:

    #ifdef MYDLL_LIB
        #define MYDLL_EXPORT Q_DECL_EXPORT
    #else
        #define MYDLL_EXPORT Q_DECL_IMPORT
    #endif
    
  2. Dll project has DEFINES += MYDLL_LIB inside it's pro file.

  3. Exported class (or only selected methods) and free functions are marked with MYDLL_EXPORT inside header files, i.e.

    class MYDLL_EXPORT MyClass {
    
    // ...
    
    };
    


回答2:

This is possible if the DLL contains files with a "C" linkage (i.e. no C++ class decorations) and if you have a header file and a .def file for the DLL. If you do not have a .def file you can create one easily by downloading the dependency walker tool from http://www.dependencywalker.com/ to get the list of exported symbols; you can save the output of this tool as text, then extract the names. You then create a text file called mylibname.def that holds:

LIBRARY mylibname

EXPORTS
    FirstExportedFunctionName
    SecondExportedFunctionName
    ...
    LastExpertedFunctionName

Then you run dlltool (in MinGW\bin):

dlltool -d mylibname.def -l mylibname.a

This will generate mylibname.a, which you add into your .pro file:

win32:LIBS += mylibname.a

You have to provide paths to all the files, or copy them to the right folders, of course.

You must also modify the header file to your third party program so that all the symbols in the DLL that you need to link to are marked for import with Q_DECL_IMPORT. I do this by declaring all functions in the .h file as:

extern "C" {
MYLIBAPI(retType) FirstFunctionName(arg list...);
MYLIBAPI(retType) SecondFunctionName(arg list...);
...
MYLIBAPI(retType) LastFunctionName(arg list...);
}

where MYLIBAPI is

#define MYLIBAPI(retType) Q_DECL_IMPORT retType

We use the MYLIBAPI(retType) format as this allows us to adjust the header file for use in both import and when creating DLLs and it also allows us to work with a wide variety of different compilers and systems.

Doing this, I managed to link QT in MinGW to a DLL that I generate using VS 2005. The routines in VS were exported as __stdcall. You should look at the dlltool documentation for adding underlines or other prefixes to the names in the library.



回答3:

You need to make the function's declaration available to the linker as well as providing the path to the dll in which it's located. Usually this is done by #including a header file that contains the declaration.

You also don't need the Q_DECL_IMPORT macro in the client - this would be used in a Qt library's header to allow client apps to import the function. A class or function would be conditionally exported/imported depending on whether the library or a client is being built. More info can be found on this page.

Is your dependency a third party dll or something that you've created?



标签: c++ qt dll