首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QT QLibrary“无法加载库*.so:(*.so:未定义符号: staticMetaObject)”

QT QLibrary“无法加载库*.so:(*.so:未定义符号: staticMetaObject)”
EN

Stack Overflow用户
提问于 2015-07-17 16:05:06
回答 1查看 3.3K关注 0票数 4

我正在处理一个大项目,在这个项目中,我试图用QLibrary动态加载一个共享库,我能够在下面的示例中再现运行时链接错误(undefined symbol: staticMetaObject):

文件夹结构:

代码语言:javascript
复制
root\
-- src\
---- TestLib\
------ TestLib.pro
------ Derived.h
------ Derived.cpp
------ TestLibModuleBridge.h
------ TestLibModuleBridge.cpp
---- TestLibCommon\
------ IBase.h
---- TestLibManager\
------ TestLibManager.pro
------ main.cpp
--lib\

TestLib文件:

代码语言:javascript
复制
# TestLib.pro

QT       -= gui

TARGET = TestLib
TEMPLATE = lib

QMAKE_CXXFLAGS += -Wall

DEFINES += TESTLIB_LIBRARY

SOURCES += Derived.cpp \
    TestLibModuleBridge.cpp

HEADERS += Derived.h \
    TestLibModuleBridge.h

INCLUDEPATH += ../TestLibCommon

unix {
    target.path = ../../lib
    INSTALLS += target
}

-

代码语言:javascript
复制
// Derived.h

#ifndef DERIVED_H
#define DERIVED_H

#include "IBase.h"

#include <iostream>

class Derived : public IBase
{
    Q_OBJECT
public:
    Derived();
    virtual ~Derived();

public:
    virtual void methodA();
    virtual void methodB();
};

#endif // DERIVED_H

-

代码语言:javascript
复制
// Derived.cpp

#include "Derived.h"

Derived::Derived()
{

}

Derived::~Derived()
{

}

void Derived::methodA()
{
    std::cout << "methodA()" << std::endl;
}

void Derived::methodB()
{
    std::cout << "methodB()" << std::endl;
}

-

代码语言:javascript
复制
// TestLibModuleBridge.h

#ifndef TESTLIBMODULEBRIDGE_H
#define TESTLIBMODULEBRIDGE_H

#include "IBase.h"

#ifdef __cplusplus
extern "C" {
#endif
    IBase* getModuleInterface();
#ifdef __cplusplus
}
#endif

#endif // TESTLIBMODULEBRIDGE_H

-

代码语言:javascript
复制
// TestLibModuleBridge.cpp

#include "TestLibModuleBridge.h"
#include "Derived.h"

IBase* getModuleInterface()
{
    return new Derived();
}

TestLibManager文件:

代码语言:javascript
复制
// TestLibManager.pro

QT       += core

QT       -= gui

TARGET = TestLibManager
CONFIG   += console
CONFIG   -= app_bundle

QMAKE_CXXFLAGS += -Wall

TEMPLATE = app

SOURCES += main.cpp

INCLUDEPATH += ../TestLibCommon

-

代码语言:javascript
复制
// main.cpp
#include <QCoreApplication>
#include <QLibrary>
#include <QDebug>

#include "IBase.h"

typedef IBase* (*ModuleGetterFunction) (void);

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QLibrary testLib("../../lib/libTestLib.so");

    if (!testLib.load())
    {
        qDebug() << "Error : " << testLib.errorString();
        exit(EXIT_FAILURE);
    }
    else
    {
        ModuleGetterFunction getModuleInterfaceFunc = (ModuleGetterFunction) testLib.resolve("getModuleInterface");

        if (getModuleInterfaceFunc)
        {
            IBase* obj = getModuleInterfaceFunc();

            obj->methodA();
            obj->methodB();
        }
    }

    return a.exec();
}

TestLibCommon Files

代码语言:javascript
复制
// IBase.h

#ifndef IBASE_H
#define IBASE_H

#include <QObject>

class IBase : public QObject
{
    Q_OBJECT
protected:
    virtual ~IBase() {}

public:
    virtual void methodA() = 0;
    virtual void methodB() = 0;
};

#endif // IBASE_H

testLib.load()Error : "Cannot load library ../../lib/libTestLib.so: (../../lib/libTestLib.so: undefined symbol: _ZN5IBase16staticMetaObjectE)"一起失败

如何解决这个问题,从Q_OBJECT宏中删除IBase.h将修复错误,但是在生产项目中,接口包含信号和插槽,而且它来自一个我们不允许更改的项目。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-17 20:11:32

在编译testlib之前,似乎还没有运行mocmoc负责为包含Q_OBJECT、宏、的类生成pro文件中的HEADERS部分。

TestLibCommon\IBase.h添加到TestLib.pro中的HEADERS可能会解决这个问题。(未经测试)。

可能改进您的解决方案:

与其使用QLibrary,不如看看QPluginLoader

QPluginLoader将为您提供一个QObject,然后您可以使用qobject_cast<T*>(pluginloader.instance())将其转换到任何您想要的接口。

下面是一个使用QPluginLoaderhttp://doc.qt.io/qt-5/qtwidgets-tools-plugandpaint-example.html的示例

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31480066

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档