PDA

View Full Version : Must include not only h files but cpp files when load a DLL using QPluginLoader



wolfguolei
29th October 2012, 05:28
Hi there, I got some problem when using QPluginLoader.
1) Firstly, I wrote the interface named “tcpPlunginInterface.h”. The content:


#ifndef TCPPLUGININTERFACE_H
#define TCPPLUGININTERFACE_H

#include "tcpclient_os.h"

class tcpPluginInterface
{
public:

virtual tcpClient_Os* getPluginInst( VhostInfo hostInfo, CtcpOpt *tcpOpt,
QObject *parent = 0) = 0;
};

QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(tcpPluginInterface,"ltcpOSDLL/1.0.0")
QT_END_NAMESPACE

#endif // TCPPLUGININTERFACE_H

2) Secondly, I wrote a class called “ltcpOS”. The instance of this class contained a function “getPluginInst”, which would return a point type.
“ltcpOS.h”:

#ifndef LTCPOS_H
#define LTCPOS_H

#include <QObject>
#include <QtPlugin>
#include "tcpPluginInterface.h"

class ltcpOS : public QObject,tcpPluginInterface
{
Q_OBJECT
Q_INTERFACES(tcpPluginInterface)
public:
ltcpOS();
~ltcpOS();

tcpClient_Os* getPluginInst( VhostInfo hostInfo, CtcpOpt *tcpOpt,
QObject *parent = 0);
//the “tcpClient_Os” is a self-defined class.

public:
tcpClient_Os *os;

signals:

public slots:

};

#endif // LTCPOS_H
“ltcpos.cpp”:

#include "ltcpos.h"

ltcpOS::ltcpOS()
{
}

ltcpOS::~ltcpOS()
{
os->deleteLater();
}

Q_EXPORT_PLUGIN2(ltcpOS,ltcpOS)

tcpClient_Os *ltcpOS::getPluginInst(VhostInfo hostInfo, CtcpOpt *tcpOpt, QObject *parent)
{
os = new tcpClient_Os(hostInfo, tcpOpt);
return os;
}
Then I compiled these file in release mode, and generated a “ltcpOS1.dll” DLL file. So I could load it and use it in other project.

The problem I encountered is, when I use a QPluginLoader to load the DLL, QT doesn’t know what the return value is. This is my code which loads the DLL:

QPluginLoader dllLoader("E:/QTProject/tcpClient3/ltcpOS1.dll");

QObject *tcpObj = dllLoader.instance();

if(!tcpObj)
{
qDebug() << dllLoader.errorString();
return;
}

tcpPluginInterface *os_inst = qobject_cast<tcpPluginInterface*>(tcpObj);

client = os_inst->getPluginInst(hostInfo, &ProtIOBuf);

client->run();

I have included the header file such like “tcpClient_os.h”, and add “QT += network” to the *.pro file, but I still get the compile errors:
error:undefined reference to `tcpClient_Os::run()'
error:undefined reference to `tcpClient_Os::slot_stop()'
…..etc


But When I add the all the cpp files (such like tcpClient_os.cpp), which contains the all implement part, to the *.pro. It’s OK. I don’t want to add those cpp files because that made my DLL useless. I’m going to be insane about that problem, it bother me more than a week…Please,help.

wysota
29th October 2012, 07:30
If you include tcpClient_os.h then you also need to provide bodies of those methods. With plugins you should only include tcpPlunginInterface.h. Moreover on Windows you need to use Q_DECL_EXPORT in your plugin classes.

wolfguolei
29th October 2012, 07:36
Thanks,wysota.
I will give it a try to see how it works...

wolfguolei
30th October 2012, 01:54
Sorry,bro.
I tried it in many ways,and seemingly it just doesn't work...

d_stranz
30th October 2012, 02:42
class ltcpOS : public QObject,tcpPluginInterface

I'm not sure I am remembering my C++ correctly, but I believe that this declaration is the same as:


class ltcpOS : public QObject, private tcpPluginInterface

which you definitely do not want. It should be declared as:


class ltcpOS : public QObject, public tcpPluginInterface

and you need to do the other things Wysota said.

wolfguolei
30th October 2012, 08:52
Sorry bro, it doesn't work...
For now I am concerning about my understanding of DLL. It package the Methods not the Specific system source. In the project, I tried line by line to figure out where the problem occurred. Now I found the procedure of loading a DLL is correct. the problem shows up when I try to use pointer "client" to call its member function(i.e. client->run(); ).the DLL would only return a pointer and it didn't "know" what is tcpClient_OS, without CPP files, the compiler didn't "know" it too...I guess the reason made me failed probably like in that way..