Results 1 to 6 of 6

Thread: Extending a plugin in a static library

  1. #1
    Join Date
    Aug 2008
    Posts
    15
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Extending a plugin in a static library

    Hello,

    I needed to extend the QPSQLDriver class do to slightly more then what the original class does. My new derived class is called PPSQLDriver (do not ask on the naming... I'm horrible at class naming). I defined this class in a static library (it does not need to be static... but it is right now). I then use this new class in several applications.

    When building QT, if I specify to *not* build the PSQL driver as a plugin (but as a library instead) everything works great.

    However if I build QT to have the PSQL driver built as a plugin I get a link error when linking to my library to my application (the library is built successfully and the application compiles successfully... it fails during linking however).

    Here are the linker errors:
    Qt Code:
    1. ...
    2. ...
    3. ../../lib/libpcccommond.a(ppsqldriver.o): In function `PPSQLDriver::commitTransaction(bool)':
    4. /home/jason/PCC/cvs/ehr/src/pcccommon/src/ppsqldriver.cpp:45: undefined reference to `QPSQLDriver::commitTransaction()'
    5. ../../lib/libpcccommond.a(ppsqldriver.o): In function `PPSQLDriver::beginTransaction()':
    6. /home/jason/PCC/cvs/ehr/src/pcccommon/src/ppsqldriver.cpp:32: undefined reference to `QPSQLDriver::beginTransaction()'
    7. ../../lib/libpcccommond.a(ppsqldriver.o): In function `PPSQLDriver::close()':
    8. /home/jason/PCC/cvs/ehr/src/pcccommon/src/ppsqldriver.cpp:25: undefined reference to `QPSQLDriver::close()'
    9. ../../lib/libpcccommond.a(ppsqldriver.o): In function `PPSQLDriver':
    10. /home/jason/PCC/cvs/ehr/src/pcccommon/src/ppsqldriver.cpp:7: undefined reference to `QPSQLDriver::QPSQLDriver(QObject*)'
    11. /home/jason/PCC/cvs/ehr/src/pcccommon/src/ppsqldriver.cpp:7: undefined reference to `QPSQLDriver::QPSQLDriver(QObject*)'
    12. ../../lib/libpcccommond.a(moc_ppsqldriver.o): In function `PPSQLDriver::qt_metacall(QMetaObject::Call, int, void**)':
    13. /home/jason/PCC/cvs/ehr/src/pcccommon/build/moc_ppsqldriver.cpp:68: undefined reference to `QPSQLDriver::qt_metacall(QMetaObject::Call, int, void**)'
    14. ../../lib/libpcccommond.a(moc_ppsqldriver.o): In function `PPSQLDriver::qt_metacast(char const*)':
    15. /home/jason/PCC/cvs/ehr/src/pcccommon/build/moc_ppsqldriver.cpp:63: undefined reference to `QPSQLDriver::qt_metacast(char const*)'
    16. ../../lib/libpcccommond.a(moc_ppsqldriver.o): In function `~PPSQLDriver':
    17. /home/jason/PCC/cvs/ehr/src/pcccommon/build/../src/ppsqldriver.h:15: undefined reference to `QPSQLDriver::~QPSQLDriver()'
    18. /home/jason/PCC/cvs/ehr/src/pcccommon/build/../src/ppsqldriver.h:15: undefined reference to `QPSQLDriver::~QPSQLDriver()'
    19. /home/jason/PCC/cvs/ehr/src/pcccommon/build/../src/ppsqldriver.h:15: undefined reference to `QPSQLDriver::~QPSQLDriver()'
    20. /home/jason/PCC/cvs/ehr/src/pcccommon/build/../src/ppsqldriver.h:15: undefined reference to `QPSQLDriver::~QPSQLDriver()'
    21. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro+0x0): undefined reference to `QPSQLDriver::staticMetaObject'
    22. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro._ZTV11PPSQLDriver[vtable for PPSQLDriver]+0x38): undefined reference to `QPSQLDriver::isOpen() const'
    23. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro._ZTV11PPSQLDriver[vtable for PPSQLDriver]+0x40): undefined reference to `QPSQLDriver::commitTransaction()'
    24. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro._ZTV11PPSQLDriver[vtable for PPSQLDriver]+0x44): undefined reference to `QPSQLDriver::rollbackTransaction()'
    25. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro._ZTV11PPSQLDriver[vtable for PPSQLDriver]+0x48): undefined reference to `QPSQLDriver::tables(QSql::TableType) const'
    26. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro._ZTV11PPSQLDriver[vtable for PPSQLDriver]+0x4c): undefined reference to `QPSQLDriver::primaryIndex(QString const&) const'
    27. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro._ZTV11PPSQLDriver[vtable for PPSQLDriver]+0x50): undefined reference to `QPSQLDriver::record(QString const&) const'
    28. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro._ZTV11PPSQLDriver[vtable for PPSQLDriver]+0x54): undefined reference to `QPSQLDriver::formatValue(QSqlField const&, bool) const'
    29. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro._ZTV11PPSQLDriver[vtable for PPSQLDriver]+0x58): undefined reference to `QPSQLDriver::escapeIdentifier(QString const&, QSqlDriver::IdentifierType) const'
    30. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro._ZTV11PPSQLDriver[vtable for PPSQLDriver]+0x60): undefined reference to `QPSQLDriver::handle() const'
    31. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro._ZTV11PPSQLDriver[vtable for PPSQLDriver]+0x64): undefined reference to `QPSQLDriver::hasFeature(QSqlDriver::DriverFeature) const'
    32. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro._ZTV11PPSQLDriver[vtable for PPSQLDriver]+0x6c): undefined reference to `QPSQLDriver::createResult() const'
    33. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro._ZTV11PPSQLDriver[vtable for PPSQLDriver]+0x70): undefined reference to `QPSQLDriver::open(QString const&, QString const&, QString const&, QString const&, int, QString const&)'
    34. ../../lib/libpcccommond.a(moc_ppsqldriver.o):(.data.rel.ro._ZTI11PPSQLDriver[typeinfo for PPSQLDriver]+0x8): undefined reference to `typeinfo for QPSQLDriver'
    35. collect2: ld returned 1 exit status
    36. ...
    37. ...
    To copy to clipboard, switch view to plain text mode 

    I'm sure the reason this isn't working correctly is because I never actually load the PSQLDriver plugin, but I'm not really sure how to do that.

    So:
    • How do I load the qsqlpsql plugin successfully?
    • Do I load the plugin in the library the defines the derived class? Or the application that uses my library?
    • Is there a way to make it "just work" transparently no matter if I build QT with the qsql_psql as a plugin or a library?
    • Does my scheme (deriving off of a plugin and putting that derived class in a library) even work when using the plugin architecture?


    Thanks for any insight.

    -Jason

  2. #2
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Extending a plugin in a static library

    • How do I load the qsqlpsql plugin successfully?
    • Do I load the plugin in the library the defines the derived class? Or the application that uses my library?
    It's not "loading" that is required here (which refers to a run-tile action) but linking against the plugin (which is a shared lib but not one of the "regular" Qt libs you are used to linkin against).

    When the "base" plugin is built as a "real" plugin (not embedded in QtSql lib but placed in its own shared lib) linking gets WAY trickier. You got to figure out where plugins are located, what is the actual name of the plugin and you have to adjust the LIBS veriable accordingly as follows :

    Qt Code:
    1. LIBS += -L$$[QT_INSTALL_PLUGINS]/sqldrivers -lqsqlpsql
    To copy to clipboard, switch view to plain text mode 

    Please note that I haven't tested this trick but it should work with a vanilla Qt install if qsql_psql plugin is available.

    A somewhat "safer", though more restrictive way to do what you want is to compile Qt in static mode and to use static plugins.

    • Is there a way to make it "just work" transparently no matter if I build QT with the qsql_psql as a plugin or a library?
    You'll need some dark qmake magic to figure whether the sql plugin exists as a plugin but it is doable :

    Qt Code:
    1. exists( $$[QT_INSTALL_PLUGINS]/sqldrivers/libqsqlpsql* ) {
    2. # plugin found do tricky linking
    3. LIBS += -L$$[QT_INSTALL_PLUGINS]/sqldrivers -lqsqlpsql
    4. } else {
    5. # plugin not found, QT += sql should do
    6. # unless of course the psql plugin is simply not built at all
    7. }
    To copy to clipboard, switch view to plain text mode 


    • Does my scheme (deriving off of a plugin and putting that derived class in a library) even work when using the plugin architecture?
    As long as the class you want to subclass is exported (only matters under Win though, AFAIK) by the shared library, linking will work so your scheme should work.
    Last edited by fullmetalcoder; 4th March 2009 at 20:12.
    Current Qt projects : QCodeEdit, RotiDeCode

  3. #3
    Join Date
    Aug 2008
    Posts
    15
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Extending a plugin in a static library

    Thanks, this looks promising (and not all that hard). I'll get back to you once I try it out (probably later on tomorrow).

  4. #4
    Join Date
    Dec 2009
    Posts
    24
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Extending a plugin in a static library

    Quote Originally Posted by ultim8 View Post
    Thanks, this looks promising (and not all that hard). I'll get back to you once I try it out (probably later on tomorrow).
    Hello ultim8,

    I am haven a similar issue, and I found your post. So I wanted to ask you how you eventually solved it?

    Regards,
    Davor

  5. #5
    Join Date
    Aug 2008
    Posts
    15
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Extending a plugin in a static library

    Quote Originally Posted by Davor View Post
    Hello ultim8,

    I am haven a similar issue, and I found your post. So I wanted to ask you how you eventually solved it?

    Regards,
    Davor
    Davor,

    I decided to go with my original method of compiling the QPSQL Driver as a library. I can't remember the road blocks that got in my way, but I could not find a suitable way of transparently making it "just work" no matter if the Driver was a plugin or a library.

    Really though, it has not been an issue to compile the QPSQL Driver as a library... the only downside is I have not been able to use the pre-built SDK's... but have had to compile Qt myself.

    If you end up coming up with a method that works for you, I would love to hear about it.

  6. #6
    Join Date
    Dec 2009
    Posts
    24
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Extending a plugin in a static library

    Ultim8,

    Good to know that at least the library version works!

    I gave up and worked around it: QSqlDatabase::driver() will give you QPSQLDriver. With the handle you can extract PGconn, and PGconn you can use with functions from pglib.dll. This way you can implement extra functionality.


    Here some brainstorming to make subclassing work with QPSQLDriver as plugin for those interested:

    If you compiled the driver as a plugin, then QPSQLDriver* drv = new QPSQLDriver(); or any subclass of QPSQLDriver will give you “undefined reference” errors. But you can initialize one with the following code:

    Qt Code:
    1. QPluginLoader l("W:/dev/Qt/4.6.0/plugins/sqldrivers/qsqlpsqld4.dll");
    2. QSqlDriverPlugin *o = qobject_cast<QSqlDriverPlugin*>(l.instance());
    3. QPSQLDriver *d = dynamic_cast<QPSQLDriver*>(o->create("QPSQL"));
    To copy to clipboard, switch view to plain text mode 

    Trolls use a factory pattern throughout the driver creation code as far as I see. So QPSQLDriverPlugin::create() is called to produce an instance of QPSQLDriver. Now if one could use the output of QPSQLDriverPlugin::create() as a base class, then one could extend QPSQLDriver, no?

    Currently, I don't see a way to do it. But then again, wouldn't something like this be farfetched? Creating a custom plugin, based on QPSQLDriver seems a better approach to me.

    Regards,
    Davor

Similar Threads

  1. How to use static mysql plugin
    By khikho in forum Qt Programming
    Replies: 7
    Last Post: 19th January 2009, 22:44
  2. Compiling QCA as static library
    By NoRulez in forum Qt Programming
    Replies: 1
    Last Post: 7th December 2008, 18:32
  3. plugin in a library
    By alisami in forum Qt Programming
    Replies: 2
    Last Post: 3rd October 2008, 18:21
  4. Replies: 16
    Last Post: 23rd May 2008, 11:12
  5. QPluginLoader not recognizing a plugin
    By KShots in forum Qt Programming
    Replies: 3
    Last Post: 29th June 2007, 15:13

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.