Results 1 to 10 of 10

Thread: How to export C symbols from qt dynamic library

  1. #1
    Join Date
    Aug 2015
    Posts
    15
    Thanks
    3
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default How to export C symbols from qt dynamic library

    i've been trying every incantation of extern "C" that I could find on the internet but I'm unable to get un-mangeled symbols from a basic Qt shared library on OS X. After two days of trying, I have no idea how to do it.
    Would someone please be kind enough to show me the correct way?

    This is all I've been able to get.

    $nm -gU ./libTestLib.1.0.0.dylib
    0000000000003550 T __ZN7TestLib10printStuffEv
    0000000000003530 T __ZN7TestLibC1Ev
    0000000000003520 T __ZN7TestLibC2Ev

    testlib_global.h
    Qt Code:
    1. #ifndef TESTLIB_GLOBAL_H
    2. #define TESTLIB_GLOBAL_H
    3.  
    4. #include <QtCore/qglobal.h>
    5.  
    6. #if defined(TESTLIB_LIBRARY)
    7. # define TESTLIBSHARED_EXPORT Q_DECL_EXPORT
    8. #else
    9. # define TESTLIBSHARED_EXPORT Q_DECL_IMPORT
    10. #endif
    11.  
    12. #endif // TESTLIB_GLOBAL_H
    To copy to clipboard, switch view to plain text mode 

    testlib.h
    Qt Code:
    1. #ifndef TESTLIB_H
    2. #define TESTLIB_H
    3.  
    4. #include "testlib_global.h"
    5.  
    6. class TESTLIBSHARED_EXPORT TestLib {
    7.  
    8. public:
    9. TestLib();
    10. void printStuff();
    11. };
    12.  
    13. #endif // TESTLIB_H
    To copy to clipboard, switch view to plain text mode 

    testlib.cpp
    Qt Code:
    1. #include "testlib.h"
    2. #include <QDebug>
    3.  
    4.  
    5. TestLib::TestLib() {}
    6.  
    7. void TestLib::printStuff() {
    8. qDebug() << "Printing Stuff";
    9. }
    To copy to clipboard, switch view to plain text mode 

    TestLib.pro
    Qt Code:
    1. #-------------------------------------------------
    2. #
    3. # Project created by QtCreator 2016-08-05T21:32:46
    4. #
    5. #-------------------------------------------------
    6.  
    7. QT += widgets
    8.  
    9. TARGET = TestLib
    10. TEMPLATE = lib
    11.  
    12. DEFINES += TESTLIB_LIBRARY
    13.  
    14. SOURCES += testlib.cpp
    15.  
    16. HEADERS += testlib.h\
    17. testlib_global.h
    18.  
    19. unix {
    20. target.path = /usr/lib
    21. INSTALLS += target
    22. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to export C symbols from qt dynamic library

    There are no C symbols in your code snippets, only C++ code.
    Did you forget to post something?

    Cheers,
    _

  3. #3
    Join Date
    Aug 2015
    Posts
    15
    Thanks
    3
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to export C symbols from qt dynamic library

    Quote Originally Posted by anda_skoa View Post
    There are no C symbols in your code snippets, only C++ code.
    Did you forget to post something?

    Cheers,
    _
    No there isn't I just didn't explain the problem correctly. The problem is that QLibrary::resolve() requires that the symbols are export as a c function. So I can load the library no problem but cannot resolve any symbols.

    Per the docs... http://doc.qt.io/qt-5/qlibrary.html

    The symbol must be exported as a C function from the library for resolve() to work. This means that the function must be wrapped in an extern "C" block if the library is compiled with a C++ compiler.

    Thats why I've tried every way I could find using extern "C" but none have worked because the exported symbols are always the same as above. Maybe there is some other way to resolve the symbols but I've not seen any other type of example.

    Robert

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to export C symbols from qt dynamic library

    You need the extern "C" block to tell the C++ compiler that a function is a C function.
    But you still need such a C function.

    Your code does not have any stand-alone (non-member) function at all.

    Cheers,
    _

  5. #5
    Join Date
    Aug 2015
    Posts
    15
    Thanks
    3
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to export C symbols from qt dynamic library

    So how do you load and use a c++ library at run time? Does it have to be compiled in at compile time?

  6. #6
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: How to export C symbols from qt dynamic library

    I might be mistaken, but it seems you're wanting to export the symbols at run-time for a Qt dynamic library itself. Symbols are exported by the linker, so I don't think you can dynamically export different symbols at run-time, etc.
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  7. #7
    Join Date
    Apr 2013
    Location
    Prague
    Posts
    258
    Thanks
    3
    Thanked 65 Times in 59 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: How to export C symbols from qt dynamic library

    You cannot link class methods "really dynamically" (using QLibrary::load() and QLibrary::resolve()) in Qt. You can only link C-functions. You find some info here

    http://stackoverflow.com/questions/2...import-a-class

    Also, the stackoverflow answer contains a bit of helpful cheese using virtual functions,

  8. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to export C symbols from qt dynamic library

    Quote Originally Posted by rwhartzell View Post
    So how do you load and use a c++ library at run time?
    You provide one or more C functions that the host program can resolve and use.

    Or when both host and plugin are using Qt, just by using Qt's plugin infrastructure
    http://doc.qt.io/qt-5/qtwidgets-tool...p-example.html

    Cheers,
    _

  9. #9
    Join Date
    Aug 2015
    Posts
    15
    Thanks
    3
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to export C symbols from qt dynamic library

    Quote Originally Posted by jefftee View Post
    I might be mistaken, but it seems you're wanting to export the symbols at run-time for a Qt dynamic library itself. Symbols are exported by the linker, so I don't think you can dynamically export different symbols at run-time, etc.
    Mostly i'm just confused about how it all works lol

    Quote Originally Posted by Radek View Post
    You cannot link class methods "really dynamically" (using QLibrary::load() and QLibrary::resolve()) in Qt. You can only link C-functions. You find some info here

    http://stackoverflow.com/questions/2...import-a-class

    Also, the stackoverflow answer contains a bit of helpful cheese using virtual functions,
    Tha was very helpful, thanks.

    Quote Originally Posted by anda_skoa View Post
    You provide one or more C functions that the host program can resolve and use.

    Or when both host and plugin are using Qt, just by using Qt's plugin infrastructure
    http://doc.qt.io/qt-5/qtwidgets-tool...p-example.html

    Cheers,
    _
    The problem i'm actually trying to solve is that I have a plugin manager class for my app that i wish to move out of my app and into a stand alone library. Your comments got me thinking I was looking entirely in the wrong direction.

    Quote Originally Posted by jefftee View Post
    I might be mistaken, but it seems you're wanting to export the symbols at run-time for a Qt dynamic library itself. Symbols are exported by the linker, so I don't think you can dynamically export different symbols at run-time, etc.


    Added after 7 minutes:


    So after all your very helpful comments and some more research I came up with another test library that I think is closer to what I was looking for.

    How does this look?

    testlib.h
    Qt Code:
    1. #ifndef TESTLIB_H
    2. #define TESTLIB_H
    3.  
    4. class TestLib {
    5.  
    6. public:
    7. TestLib();
    8. virtual ~TestLib();
    9.  
    10. virtual int getValue();
    11. virtual void setValue(int y);
    12.  
    13. private:
    14. int x;
    15. };
    16.  
    17. #endif // TESTLIB_H
    To copy to clipboard, switch view to plain text mode 

    testlib.cpp
    Qt Code:
    1. #include "testlib.h"
    2. #include <QtCore/QDebug>
    3.  
    4. extern "C" TestLib* create_obj() {
    5. return new TestLib;
    6. }
    7.  
    8. extern "C" void destroy_obj(TestLib* obj) {
    9. delete obj;
    10. }
    11.  
    12. TestLib::TestLib() {
    13. x = 0;
    14. }
    15.  
    16. TestLib::~TestLib() {}
    17.  
    18. int TestLib::getValue() {
    19. return x;
    20. }
    21.  
    22. void TestLib::setValue(int y) {
    23. x = y;
    24. }
    To copy to clipboard, switch view to plain text mode 

    main.cpp
    Qt Code:
    1. #include "../TestLib/testlib.h"
    2. #include <QtCore/QLibrary>
    3. #include <QtCore/QDebug>
    4.  
    5. int main(int argc, char *argv[]) {
    6. Q_UNUSED(argc);
    7. Q_UNUSED(argv);
    8.  
    9. QLibrary extLib("TestLib");
    10. if (!extLib.load()) {
    11. qDebug() << extLib.errorString();
    12. exit(1);
    13. }
    14.  
    15. TestLib* (*create)();
    16. void (*destroy)(TestLib*);
    17.  
    18. create = (TestLib* (*)())extLib.resolve("create_obj");
    19. destroy = (void (*)(TestLib*))extLib.resolve("destroy_obj");
    20.  
    21. TestLib* testLib = (TestLib*) create();
    22.  
    23. int x, y = 5;
    24. testLib->setValue(y);
    25. qDebug() << "x =" << (x = testLib->getValue());
    26.  
    27. destroy(testLib);
    28.  
    29. return 0;
    30. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by rwhartzell; 9th August 2016 at 21:41.

  10. #10
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to export C symbols from qt dynamic library

    Typically a plugin architecture defines one or more virtual classes which provide the "interface" methods that all compatible plugins must implement. All of the methods in the interface class are pure virtual, that is, they have no code behind them and it is impossible to construct an instance. The plugin internally implements a concrete class that inherits from the interface class and provides implementations (i.e. real code) for the virtual functions defined by the interface. So in your example, the interface class is ITestLib, and has two virtual methods, int getValue() and void setValue( int ).

    The "create" method is present in all plugins (if you choose to do it that way) and returns an ITestLib pointer to a concrete instance. So in your case, class TestLib inherits publicly from class ITestLib and provides concrete implementations of getValue() and setValue(). create_obj() as implemented in TestLib returns a TestLib* instance as an ITestLib * pointer.

    So your main() would be implemented as:

    Qt Code:
    1. #include "../TestLib/ITestLib.h"
    2. #include <QtCore/QLibrary>
    3. #include <QtCore/QDebug>
    4.  
    5. int main(int argc, char *argv[]) {
    6. Q_UNUSED(argc);
    7. Q_UNUSED(argv);
    8.  
    9. QLibrary extLib("TestLib");
    10. if (!extLib.load()) {
    11. qDebug() << extLib.errorString();
    12. exit(1);
    13. }
    14.  
    15. ITestLib* (*create)();
    16. void (*destroy)(ITestLib*);
    17.  
    18. create = (ITestLib* (*)())extLib.resolve("create_obj");
    19. destroy = (void (*)(ITestLib*))extLib.resolve("destroy_obj");
    20.  
    21. ITestLib* testLib = (ITestLib*) create();
    22.  
    23. int x, y = 5;
    24. testLib->setValue(y);
    25. qDebug() << "x =" << (x = testLib->getValue());
    26.  
    27. destroy(testLib);
    28.  
    29. return 0;
    30. }
    To copy to clipboard, switch view to plain text mode 

    and ITestLib.h would look like:

    Qt Code:
    1. #ifndef ITESTLIB_H
    2. #define ITESTLIB_H
    3.  
    4. class ITestLib
    5. {
    6. public:
    7. virtual int getValue() = 0;
    8. virtual void setValue(int y) = 0;
    9.  
    10. protected:
    11. ITestLib() {}
    12. virtual ~ITestLib() {}
    13. };
    14.  
    15. #endif // ITESTLIB_H
    To copy to clipboard, switch view to plain text mode 

    TestLib.h would be the same, except that now class TestLib inherits from ITestLib:

    Qt Code:
    1. #include "ITestLib.h"
    2.  
    3. class TestLib : public ITestLib
    4. {
    5. public:
    6. TestLib();
    7. // ...
    8. };
    To copy to clipboard, switch view to plain text mode 
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Export created files in shared library into separate folder
    By alizadeh91 in forum Qt Programming
    Replies: 1
    Last Post: 9th December 2012, 11:49
  2. Dynamic library on Mac, Library not loaded
    By grayfox in forum Newbie
    Replies: 2
    Last Post: 2nd July 2011, 03:42
  3. Using symbols from loading application in shared library
    By barteksch in forum Qt Programming
    Replies: 1
    Last Post: 19th November 2010, 18:08
  4. Replies: 4
    Last Post: 20th May 2009, 11:20
  5. Library export macros on windows
    By jonks in forum Qt Programming
    Replies: 1
    Last Post: 10th May 2009, 04:07

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.