一.问题概述
最近需要把QT程序从5.12的桌面环境移植到QT6.6的android下,项目中有很多DLL库要重新编译为so文件,移植到android环境然后调用,中间有很多坑,虽然大体和桌面系统用法相同,但细节上还是有区别的,尤其是so库的调用方法上,过程中也是debug了两天才解决,如果你也遇到了同样问题,可以参考本文的解决方法。
说明:一下在android的平板系统上可以跑qml框架和widget框架的QT程序,移植方法无区别
之前在《QT实战系列》专栏中有详细阐述过QT5.12环境下桌面系统中自制DLL及调用方法,文章链接:
https://blog.csdn.net/xieliru/article/details/135581244
二.解决方法与示例
1.自己新建一个DLL项目文件
2.Dll代码实现
(1)dll.h
#ifndef DLL_PRO_H
#define DLL_PRO_H
#include "DLL_Pro_global.h"
class DLL_PRO_EXPORT DLL_Pro
{
public:
DLL_Pro();
int add(int a,int b);
};
//非类
extern "C"{
DLL_PRO_EXPORT int helloWorld();
DLL_PRO_EXPORT int add(int a,int b);
}
#endif // DLL_PRO_H
(2)dll.cpp
#include "dll.h"
DLL_Pro::DLL_Pro() {}
int DLL_Pro::add(int a,int b)
{
return a+ b;
}
int helloWorld()
{
return 1;
}
int add(int a, int b)
{
return a + b;
}
(3)编译出来的so库
3.调用dll库程序
(1)代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <dll.h>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
DLL_Pro a;
int t = a.add(7,8);
int aa = helloWorld(); //调用类外的C格式函数
int bb =add(8, 8);
QString tt = "android 显示后 ok: "+ QString::number(t) + " - " +QString::number(aa) + " - " +QString::number(bb);
ui->label->setText(tt);
}
(2)pro文件
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h \
dll.h \
DLL_Pro_global.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
LIBS += -L$$PWD/../build-aqt-Qt_6_6_1_Clang_arm64_v8a-Debug/bin/ -lDLL_Pro_arm64-v8a
contains(ANDROID_TARGET_ARCH,arm64-v8a) {
ANDROID_EXTRA_LIBS = \
$$PWD/../build-aqt-Qt_6_6_1_Clang_arm64_v8a-Debug/bin/libDLL_Pro_arm64-v8a.so \
}
(3)重点:
LIBS += -L$$PWD/../build-aqt-Qt_6_6_1_Clang_arm64_v8a-Debug/bin/ -lDLL_Pro_arm64-v8a
contains(ANDROID_TARGET_ARCH,arm64-v8a) {
ANDROID_EXTRA_LIBS = \
$$PWD/../build-aqt-Qt_6_6_1_Clang_arm64_v8a-Debug/bin/libDLL_Pro_arm64-v8a.so \
这两个都必须添加才可以,否则调用so库都不正常,不加入LIBS行会导致找不到so库,不加入contains行会导致程序起来后闪退。
其中contains这行可以通过如下方法加入so库后自动产生:
4.总结:
QT android下编译so库其实和桌面系统编译dll库步骤基本一致;
但调用so库和调用dll还是有区别的,按上述方法调用就能正常工作了,希望本文对你有帮助。