gpt4 book ai didi

c++ - QT QLibrary "Cannot load library *.so: (*.so: undefined symbol: staticMetaObject)"

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:52:27 27 4
gpt4 key购买 nike

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

文件夹结构:

root\
-- src\
---- TestLib\
------ TestLib.pro
------ Derived.h
------ Derived.cpp
------ TestLibModuleBridge.h
------ TestLibModuleBridge.cpp
---- TestLibCommon\
------ IBase.h
---- TestLibManager\
------ TestLibManager.pro
------ main.cpp
--lib\

测试库文件:

# 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
}

-

// 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

-

// 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;
}

-

// TestLibModuleBridge.h

#ifndef TESTLIBMODULEBRIDGE_H
#define TESTLIBMODULEBRIDGE_H

#include "IBase.h"

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

#endif // TESTLIBMODULEBRIDGE_H

-

// TestLibModuleBridge.cpp

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

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

TestLibManager 文件:

// TestLibManager.pro

QT += core

QT -= gui

TARGET = TestLibManager
CONFIG += console
CONFIG -= app_bundle

QMAKE_CXXFLAGS += -Wall

TEMPLATE = app

SOURCES += main.cpp

INCLUDEPATH += ../TestLibCommon

-

// 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 文件

// 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() 失败并显示 错误:“无法加载库 ../../lib/libTestLib.so: (../../lib/libTestLib.所以: undefined symbol :_ZN5IBase16staticMetaObjectE)"

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

最佳答案

看起来像moc在编译测试库之前还没有运行。 moc负责生成 staticMetaObject对于包含 Q_OBJECT 的类宏列在HEADERS下pro 文件中的部分。

添加TestLibCommon\IBase.hHEADERS在 TestLib.pro 中应该可以解决这个问题。 (未经测试)。


您的解决方案可能的改进:
而不是使用 QLibrary看看QPluginLoader .

QPluginLoader 会给你一个 QObject然后您可以使用 qobject_cast<T*>(pluginloader.instance()) 将其转换为您想要的任何界面

这是一个使用 QPluginLoader 的例子: http://doc.qt.io/qt-5/qtwidgets-tools-plugandpaint-example.html

关于c++ - QT QLibrary "Cannot load library *.so: (*.so: undefined symbol: staticMetaObject)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31480066/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com