PDA

View Full Version : Writing a shared library with Qt



freesky
27th January 2015, 08:09
Hello, guys! Could you help me, please?

First, excuse me for my English because I'm from Russia (:
I'm working on some project which consists of two parts: user-friendly GUI and console interface for batch processing. I decided to carry out common things in shared library (dll/so). I've read a lot of tutorials on the Internet and official Qt documentation, but there is still one point on which I've stucked.

From Qt doc:

When deploying the library, there should be no dependency to the internal headers footronics/device.h or ui_widget.h.

This can be avoided by making use of the Pointer to implementation idiom described in various C++ programming books. For classes with value semantics, consider using QSharedDataPointer.
My library contains 4 headers (3 with my code and one for #defines with Q_DECL*) and 3 cpp files, but I want to export only one function from one header. I realize that for linking with my app user only needs .lib file and only one header (from which I've exported my function). All other headers are just internal for my lib (as in example footronics/device.h and ui_widget.h) and shouldn't be visible by user, right? So I puzzled how to manage such internal dependencies (I'm not familiar with PIMPL mechanism).

One more thing: I'm using GNU Scientific Library and have #includes such as <gsl/file_name.h> and so on. Is it OK to have such includes in my library project?

Thank you all, guys. Any help is greatly appreciated!

anda_skoa
27th January 2015, 09:57
How does your only header look like?
Is that single function just using standard types or its arguments and return value or is it using library provided types?

Cheers,
_

freesky
27th January 2015, 10:00
Project file

QT -= gui

TARGET = InverseSolverCore
TEMPLATE = lib

DEFINES += INVERSESOLVERCORE_LIBRARY

SOURCES += \
global.cpp \
integrator.cpp \
minimizator.cpp \
parser.cpp

HEADERS +=\
inversesolvercore_global.h \
global.h \
integrator.h \
minimizator.h \
parser.h

LIBS += -lgsl -lgslcblas -lm

unix {
target.path = /usr/bin
INSTALLS += target
}

Main header file:

#ifndef INVERSESOLVERCORE_GLOBAL_H
#define INVERSESOLVERCORE_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(INVERSESOLVERCORE_LIBRARY)
# define INVERSESOLVERCORESHARED_EXPORT Q_DECL_EXPORT
#else
# define INVERSESOLVERCORESHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // INVERSESOLVERCORE_GLOBAL_H

Header with needed function:

// Minimization routines
#ifndef MINIMIZATOR_H
#define MINIMIZATOR_H

#include <gsl/gsl_math.h>
#include <gsl/gsl_multimin.h>
#include <gsl/gsl_vector.h>
#include "integrator.h"
#include "global.h"
#include "inversesolvercore_global.h"

INVERSESOLVERCORESHARED_EXPORT int minimizeConstants(double &rsquared, qulonglong &iters, double &simplex_size);

#endif // MINIMIZATOR_H

As you can see I've #included some local headers such as integrator.h and global.h

anda_skoa
27th January 2015, 13:53
As you can see I've #included some local headers such as integrator.h and global.h

Why?
The function declarationdoesn't need any of them, all its types are standard types (or a Qt typedef which you probably get through qglobal.h)

Cheers,
_

freesky
27th January 2015, 14:12
But in my minimizeConstants(...) function I've calls to the routines which are implemented in other .cpp files and declared in corresponding headers. Some internal functions are using my own typedef'ed structs (from global.h). I can't build a library without those internal headers! So this is the trouble point for me
Thank you for your help

anda_skoa
27th January 2015, 15:30
But you don't need any of these include in the header.

Just in the source file that contains the implementation of minimizeConstants()

Cheers,
_

freesky
27th January 2015, 16:40
Hmm... So if I move all #includes into .cpp files from my .h... then I'll just compile my library, right? But what headers should I maintain with my binary lib after that? Only minimizator.h and inversesolvercore_global.h? And what about includes such as <gsl/filename.h>?

d_stranz
27th January 2015, 18:43
If the only function your app sees is the minimizeConstants() function, then the only header file that needs to be in the header is the one that defines INVERSESOLVERCORESHARED_EXPORT. You can even get rid of that file and move the #define into the header that declares minimizeConstants(). Then the only files you need to provide are that header and the library that will link to your app.

freesky
27th January 2015, 19:58
Thank you so much! Things are much clearer now (: And the last question about GSL headers. I'm using datatypes which are provided by GSL lib and have included needed headers. Is that OK? (Because it seemes like footronics example in Qt doc). And one more thing: should I link my app against GSL and BLAS lib if I using my own library which has been already built with GSL and BLAS libs support (like in project file example above)?

anda_skoa
28th January 2015, 09:32
And the last question about GSL headers. I'm using datatypes which are provided by GSL lib and have included needed headers. Is that OK?

In the cpp file?
Of course, you need to otherwise you can't use the types.
Not in the header of course, we already determined you don't need anything else there.


And one more thing: should I link my app against GSL and BLAS lib if I using my own library which has been already built with GSL and BLAS libs support (like in project file example above)?

In general yes, the symbols need to come from somewhere when the linker tries to solve the symbols requirements upon linking the application.
But you can easily try this yourself, compilers sometimes behave differently.

Cheers,
_

freesky
28th January 2015, 12:30
Thank you guys a lot! I hope I understand all trouble points (:
EDIT:
I've used INVERSESOLVERCORESHARED_EXPORT in header file for needed function. Is there any difference between using it in .h file or .cpp file?

anda_skoa
28th January 2015, 14:05
I've used INVERSESOLVERCORESHARED_EXPORT in header file for needed function. Is there any difference between using it in .h file or .cpp file?

It needs to be at the declaration (in the header) because the code using the function needs to see it as well.

Cheers,
_

freesky
28th January 2015, 14:09
As I understand, all internal headers should be #included in .cpp files. In .h files I can #include only other public headers (which are also will be accessible by user) and headers with needed public exported functions, right?

anda_skoa
28th January 2015, 16:09
You only include in a header what is necessary for the header to be valid within the context of where it is used.

For example in your single function header, there is no need for any include since you are only using basic types like "double".

Cheers,
_

freesky
28th January 2015, 17:08
Thank you for explanation. Examples in "Header file considerations" section of Qt doc just confused me a bit (: