Qt 5.3 shared lib problems [SOLVED]



  • I am attempting to create a cross-platform shared library to be used by both a server and client XML API.

    The library has been created using the obligatory export / import macros and compiles with no errors.
    However, when creating the client application, functions called from the library produce an error.

    @
    error: too many arguments to the function - xmlrpc_api.cpp
    @

    even though the correct number of arguments are supplied as defined.

    The applicable abbreviated code is as follows - library ... global.hpp:
    @
    #include <QtCore/QtGlobal>

    #if defined(XMLRPCSHARED_LIBRARY)

    ifdef Q_OS_WIN32

    define XMLRPCLIB_EXPORT __declspec(dllexport)

    else

    define XMLRPCLIB_EXPORT Q_DECL_EXPORT

    endif

    #else

    ifdef Q_OS_WIN32

    define XMLRPCLIB_EXPORT __declspec(dllimport)

    else

    define XMLRPCLIB_EXPORT Q_DECL_IMPORT

    endif

    #endif
    @

    library ... xmlserver.hpp
    @
    #include "global.hpp"

    class XMLRPCLIB_EXPORT XmlRpcServer : public QObject
    {
    Q_OBJECT

    public:
        XMLRPCLIB_EXPORT XmlRpcServer(QObject parent=0);
        XMLRPCLIB_EXPORT void addMethod(QString method, QObject *responseObject, const char* responseSlot);
    

    . . .
    @

    server app - api definition:
    @
    extern "C" void addMethod(QString method,QObject *responseObject, const char *responseString);

    #include "xmlrpc_api.hpp"

    XmlRpcApiServer::XmlRpcApiServer(QObject* parent) : QObject(parent)
    {
    QLibrary library("xmlrpc.dll");
    if ( !library.load() ) qDebug() << library.errorString();
    if ( library.load() ) qDebug() << "library loaded";
    typedef void (*XmlRpcServer) ();
    // void addMethod(QString method,QObject responseObject,const char responseSlot);
    XmlRpcServer addMethod = (XmlRpcServer) QLibrary::resolve("library" , "addMethod");
    if (addMethod)
    {
    addMethod("examples.getStateName", this, "callState");
    . . .
    @

    The defines specified in the global.hpp is included in the .pro of the library.
    The compiled shared library is included in the .pro of the client app as LIBS += -Llib -lxml.dll (-lxml on Linux)

    The error occurs identically on both windows and Linux.

    What am I missing?


  • Lifetime Qt Champion

    Hi,

    @
    #if defined(XMLRPCSHARED_LIBRARY)

    define XMLRPCLIB_EXPORT Q_DECL_EXPORT

    #else

    define XMLRPCLIB_EXPORT Q_DECL_IMPORT

    #endif
    @

    Is enough, these two macros already manages all platform variants.

    You don't need to export every method since you export the class.

    AFAIK, you can "extern" a class method.

    On windows, you don't like to dll but to lib files.

    Also, why do you use QLibrary in your server ? Can't you just link to your library ?



  • OK...

    I have changed the global statement to comply with the suggestion by SGalst to look like:
    @
    #include <QtCore/QtGlobal>

    #if defined(XMLRPCSHARED_LIBRARY)

    define XMLRPCLIB_EXPORT Q_DECL_EXPORT

    #else

    define XMLRPCLIB_EXPORT Q_DECL_IMPORT

    #endif
    @

    The export of methods has been removed and the extern call is now on the class not the method...

    However, the same error is still exhibited - not the whole solution.


  • Lifetime Qt Champion

    Again, why use external and QLibary ? Since you own the library you can link to it without any problem



  • Ok...OK my bad. I forgot to mention that I was able to eliminate the library load and use the library directly albeit with the errors.

    Thank you for catching my mistake.


  • Lifetime Qt Champion

    Can you show how your latest code looks like ?



  • Ah thanks SGaist. The project as it stands now is as follows:

    global.hpp
    @
    #include <QtCore/QtGlobal>

    #if defined(XMLRPCSHARED_LIBRARY)

    define XMLRPCLIB_EXPORT Q_DECL_EXPORT

    #else

    define XMLRPCLIB_EXPORT Q_DECL_IMPORT

    #endif
    @

    xmlserver.hpp
    @
    #include "xmlrpc_globals.hpp"

    class XMLRPCLIB_EXPORT XmlRpcServer : public QObject
    {
    Q_OBJECT

    public:
    XmlRpcServer(const QHostAddress &address = QHostAddress::Any, quint16 port = 8080, QObject* parent = 0);
    XmlRpcServer(const QHostAddress &address = QHostAddress::Any, quint16 port = 8080, QList<QHostAddress> *allowedAddresses = 0, QObject parent = 0);
    XmlRpcServer(quint16 port = 8080, QObject
    parent = 0);
    virtual ~XmlRpcServer();

    void addMethod(QString method, QObject *responseObject, const char* responseSlot);
    void removeMethod(QString method);
    QHostAddress getServerAddress();
    

    @

    server app - api definition
    @
    #include "xmlrpc_globals.hpp"
    #include "xmlrpcserver.hpp"

    class XmlRpcApiServer : public QObject
    {
    Q_OBJECT

    public:
    explicit XmlRpcApiServer(QObject* parent = 0);
    virtual ~XmlRpcApiServer();

    public slots:

    private slots:
    void nix();
    QString callState(int i);

    private:
    XmlRpcServer* server;
    };
    @

    With egg on my face...this code compiles with no errors and the server app runs without error.

    Not sure if this means problem solved or not. The task now is to be sure the call to addMethod() is actually performed and actually works.


  • Lifetime Qt Champion

    Should be solved indeed :)

    One question though, why "QList<QHostAddress> *allowedAddresses = 0" in your second constructor ? Are you modifying that list ?
    If not, then just pass a const reference with an empty list as default value



  • This base code and my be heavily modified. That constructor, as you say, may go away as development continues.

    Thanks for all your help.


  • Lifetime Qt Champion

    You're welcome !

    Happy refactoring !


Log in to reply
 

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