c++ - 我需要整合我的 c++ 代码和 qml。但是我在使用 qmlRegisterType 时遇到了许多错误“未定义对‘Middlemen::staticMetaObject’的引用”
问题描述
我需要能够从 qml(javascript) 调用我的 c++ 函数。但是当我尝试通过使用将类注册为 qml 类型时似乎出现错误qmlRegisterType
我使用 cmakeCMakeLists.txt
来构建我的项目。我没有使用 qt-creator。
主文件
#include <iostream>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "../include/middlemen.hpp"
int main(int argc, char *argv[]){
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<Middlemen>("com.ImSteg.Middlemen", 1, 0, "Middlemen");
QQmlApplicationEngine engine;
app.setOrganizationName("European University of Lefke");
app.setOrganizationDomain("http://www.eul.edu.tr/en/");
app.setApplicationName("ImSteg");
const QUrl url(QStringLiteral("qrc:/pages/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &obj_url){
if(!obj && url == obj_url)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
中间人.hpp
#ifndef MIDDLEMEN_HPP
#define MIDDLEMEN_HPP
#include <QObject>
#include <QString>
class Middlemen : public QObject{
Q_OBJECT
public:
explicit Middlemen(QObject *parent = 0);
Q_INVOKABLE QString Embed(QString message, QString password, QString img_path, QString stego_path);
Q_INVOKABLE QString Extract(QString password, QString img_path);
~Middlemen();
};
#endif
中间人.cpp
#include "../include/middlemen.hpp"
#include "../include/steganography.hpp"
Middlemen::Middlemen(QObject *parent) : QObject(parent) { }
QString Middlemen::Embed(QString message, QString password, QString img_path, QString stego_path){
Steganography steg(message.toStdString(), password.toStdString(), img_path.toStdString(), stego_path.toStdString());
return QString::fromStdString(steg.Embedding());
}
QString Middlemen::Extract(QString password, QString img_path){
Steganography steg(password.toStdString(), img_path.toStdString());
return QString::fromStdString(steg.Extraction());
}
Middlemen::~Middlemen(){ }
CMakeLists.txt
cmake_minimum_required(VERSION 3.16.4)
project(image-steganography)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(OpenCV REQUIRED)
find_package(Qt5 COMPONENTS Qml Quick REQUIRED)
qt5_add_resources(qml_QRC gui/qml.qrc)
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(include)
include_directories(third_party/sha256/include)
file(GLOB SOURCES "src/*.cpp" "third-party/sha256/src/*.cpp")
add_executable(ImSteg ${SOURCES} ${qml_QRC})
target_link_libraries(ImSteg ${OpenCV_LIBS})
target_link_libraries(ImSteg Qt5::Qml Qt5::Quick)
我得到的错误
[ 10%] Automatic MOC and UIC for target ImSteg
[ 10%] Built target ImSteg_autogen
[ 20%] Generating qrc_qml.cpp
Scanning dependencies of target ImSteg
[ 30%] Building CXX object CMakeFiles/ImSteg.dir/ImSteg_autogen/mocs_compilation.cpp.o
[ 40%] Building CXX object CMakeFiles/ImSteg.dir/src/convert.cpp.o
[ 50%] Building CXX object CMakeFiles/ImSteg.dir/src/main.cpp.o
[ 60%] Building CXX object CMakeFiles/ImSteg.dir/src/middlemen.cpp.o
[ 70%] Building CXX object CMakeFiles/ImSteg.dir/src/steganography.cpp.o
[ 80%] Building CXX object CMakeFiles/ImSteg.dir/third-party/sha256/src/sha256.cpp.o
[ 90%] Building CXX object CMakeFiles/ImSteg.dir/qrc_qml.cpp.o
[100%] Linking CXX executable ImSteg
/usr/bin/ld: CMakeFiles/ImSteg.dir/src/main.cpp.o: in function `int qmlRegisterType<Middlemen>(char const*, int, int, char const*)':
main.cpp:(.text._Z15qmlRegisterTypeI9MiddlemenEiPKciiS2_[_Z15qmlRegisterTypeI9MiddlemenEiPKciiS2_]+0x38): undefined reference to `Middlemen::staticMetaObject'
/usr/bin/ld: main.cpp:(.text._Z15qmlRegisterTypeI9MiddlemenEiPKciiS2_[_Z15qmlRegisterTypeI9MiddlemenEiPKciiS2_]+0x1b6): undefined reference to `Middlemen::staticMetaObject'
/usr/bin/ld: CMakeFiles/ImSteg.dir/src/main.cpp.o: in function `QtPrivate::MetaObjectForType<Middlemen*, void>::value()':
main.cpp:(.text._ZN9QtPrivate17MetaObjectForTypeIP9MiddlemenvE5valueEv[_ZN9QtPrivate17MetaObjectForTypeIP9MiddlemenvE5valueEv]+0x7): undefined reference to `Middlemen::staticMetaObject'
/usr/bin/ld: CMakeFiles/ImSteg.dir/src/main.cpp.o: in function `QMetaTypeIdQObject<Middlemen*, 8>::qt_metatype_id()':
main.cpp:(.text._ZN18QMetaTypeIdQObjectIP9MiddlemenLi8EE14qt_metatype_idEv[_ZN18QMetaTypeIdQObjectIP9MiddlemenLi8EE14qt_metatype_idEv]+0x3b): undefined reference to `Middlemen::staticMetaObject'
/usr/bin/ld: CMakeFiles/ImSteg.dir/src/main.cpp.o:(.data.rel.ro._ZTVN11QQmlPrivate11QQmlElementI9MiddlemenEE[_ZTVN11QQmlPrivate11QQmlElementI9MiddlemenEE]+0x10): undefined reference to `Middlemen::metaObject() const'
/usr/bin/ld: CMakeFiles/ImSteg.dir/src/main.cpp.o:(.data.rel.ro._ZTVN11QQmlPrivate11QQmlElementI9MiddlemenEE[_ZTVN11QQmlPrivate11QQmlElementI9MiddlemenEE]+0x18): undefined reference to `Middlemen::qt_metacast(char const*)'
/usr/bin/ld: CMakeFiles/ImSteg.dir/src/main.cpp.o:(.data.rel.ro._ZTVN11QQmlPrivate11QQmlElementI9MiddlemenEE[_ZTVN11QQmlPrivate11QQmlElementI9MiddlemenEE]+0x20): undefined reference to `Middlemen::qt_metacall(QMetaObject::Call, int, void**)'
/usr/bin/ld: CMakeFiles/ImSteg.dir/src/main.cpp.o:(.data.rel.ro._ZTIN11QQmlPrivate11QQmlElementI9MiddlemenEE[_ZTIN11QQmlPrivate11QQmlElementI9MiddlemenEE]+0x10): undefined reference to `typeinfo for Middlemen'
/usr/bin/ld: CMakeFiles/ImSteg.dir/src/middlemen.cpp.o: in function `Middlemen::Middlemen(QObject*)':
middlemen.cpp:(.text+0x26): undefined reference to `vtable for Middlemen'
/usr/bin/ld: CMakeFiles/ImSteg.dir/src/middlemen.cpp.o: in function `Middlemen::~Middlemen()':
middlemen.cpp:(.text+0x3e7): undefined reference to `vtable for Middlemen'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/ImSteg.dir/build.make:264: ImSteg] Error 1
make[1]: *** [CMakeFiles/Makefile2:97: CMakeFiles/ImSteg.dir/all] Error 2
make: *** [Makefile:104: all] Error 2
如何解决此错误。
解决方案
我最终从 cmake 切换到 qmake。CMake 可能是最佳选择,但对于 Qt 应用程序,qmake 是最佳选择。
ImSteg.pro
QT += quick qml
CONFIG += c++17
CONFIG += warn_off
TARGET = ImSteg
SOURCES += src/main.cpp \
src/convert.cpp \
src/steganography.cpp \
src/middlemen.cpp \
third-party/sha256/src/sha256.cpp
RESOURCES += gui/qml.qrc
HEADERS += include/convert.hpp \
include/steganography.hpp \
include/middlemen.hpp \
third-party/sha256/include/sha256.hpp
unix: CONFIG += link_pkgconfig
unix: PKGCONFIG += opencv4
推荐阅读
- python - Pandas:根据子集在另一个数据框中查找重复项
- apache-spark-sql - spark sql 协议缓冲区支持
- c# - 如何比较 PictureBox 和资源数据之间的两个图像?
- laravel - 返回重定向 Laravel
- reactjs - 使用 React JS 从 Spotify API 调用多个播放列表
- terraform - 在触发器 Terraform 上销毁资源
- linux - 使用 awk 进行计算,在输出中获得额外的行
- javascript - this.state.persons.map 不是函数,但 people 已经是一个数组
- android - 封闭轨道中的 apk 大小与 Play 控制台中显示的大小差异?
- php - 如何定义一个方程来根据权重计算对象(餐厅)的排名