当前页面访问量: 47

Linux下编译生成VAPSXT动态链接库.so文件并动态加载

Posted by

系列索引:VAPS XT4.2.1入门系列索引

开发环境

软件 版本
OS Deepin 20.2
GCC 8.3
Qt 5.15.1
VAPS XT 4.2.1

示例代码官方示例代码:C:\Presagis\VAPS_XT_4_2_1\Projects\Examples\DrawingIntegrationExample

首先按照VAPS XT4.2.1安装配置配置好开发环境。

Porting layer配置文件

先在C:\Presagis\VAPS_XT_4_2_1\Configs\Targets下有跨平台生成编译代码的配置文件*.cfg,因为目标平台是linux,所以我们在此使用linux64.cfg,复制一份并重命名为linux64_so.cfg表示用于编译linux64位平台下so文件。

配置文件地址为:linux64_so.cfg(此文件由Presagis官方技术人员提供,我在此基础上修改一些参数)。

导出代码

打开VAPS软件

default

点击文件中的新建

new

填入项目名称和项目文件保存位置

new done

下图为本文使用的官方示例

example

其中DrawingIntegration.vprj为示例过程文件,我们将其导入刚刚创建的新根项目中。

点击File -> Import into project ,准备导入

import

输入子项目位置

input

点击OK后软件会自动解析到根项目中,

open

选择代码运行的目标平台,即之前提到的配置文件linux64_so.cfg

target

选择需要生成代码的软件,右击选择生成代码和资源

generate

软件会自动生成代码,结果如下:

result

将所有代码复制到linux系统之下的任意文件夹中。

编译

先编译必须的库文件,因为东西不少,所以我写成脚本,这样编译的时候方便一些。

# !/bin/sh

cd /home/hyper/VAPS_XT_4_2_1/src/make

cg_make.sh -tgt 1 -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects makefile.mak -2

cd /home/hyper/VAPS_XT_4_2_1/src/RT/make

cg_make.sh -tgt 1 -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects makefile.mak -2

cd /home/hyper/VAPS_XT_4_2_1/src/Main/Default/make

cg_make.sh -tgt 1 -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects makefile.mak -2

cd /home/hyper/VAPS_XT_4_2_1/src/XTObjects/make

cg_make.sh -tgt 1 -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects makefile.mak -2

cd /home/hyper/VAPS_XT_4_2_1/src/XTTypes/make

cg_make.sh -tgt 1 -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects makefile.mak -2

cd /home/hyper/VAPS_XT_4_2_1/src/ThirdParty/FreeType/make

cg_make.sh -tgt 1 -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects makefile.mak -2

cd /home/hyper/VAPS_XT_4_2_1/src/ThirdParty/PNG/make

cg_make.sh -tgt 1 -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects makefile.mak -2

cd /home/hyper/VAPS_XT_4_2_1/src/Utils/XTResourceCompiler/make

cg_make.sh -tgt 1 -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects makefile.mak -2

cd /home/hyper/VAPS_XT_4_2_1/src/Integration/DrawingIntegration/make

cg_make.sh -tgt 1 -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects makefile.mak -2

cd /home/hyper/VAPS_XT_4_2_1/src/Ports/Target/linux/make

cg_make.sh -tgt 1 -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects makefile.mak -2

cd /home/hyper/VAPS_XT_4_2_1/src/Ports/Display/OpenGL/make

cg_make.sh -tgt 1 -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects makefile.mak -2

cd /home/hyper/VAPS_XT_4_2_1/src/Ports/OS/linux/make

cg_make.sh -tgt 1 -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects makefile.mak -2

cd /home/hyper/VAPS_XT_4_2_1/src/ThirdParty/FTGL/make

cg_make.sh -tgt 1 -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects makefile.mak -2

当然如果你是一个一个测试编译的话,就是报错缺少什么就添加什么。

使用方法为

sh build.sh linux64_so rebuild

接下来编译so文件,在源码中mak文件所在的文件夹中,打开终端执行:

cg_make.sh -tgt linux64_so -vrpjdir /home/hyper/VAPS_XT_4_2_1/Projects/StandardRootProjects HUDDrawingIntegrationExample.mak -rebuild

build

就会在源码文件夹内生成*.so文件。

先看一下是否生成成功:

$ ldd -r HUDDrawingIntegrationExample_linux64_so.so
        linux-vdso.so.1 (0x00007ffdd33de000)
        libGLU.so.1 => /lib/x86_64-linux-gnu/libGLU.so.1 (0x00007ffb923b4000)
        libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007ffb9232d000)
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ffb921a9000)
        libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007ffb92068000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007ffb9205e000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ffb91edb000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ffb91ebf000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffb91cfe000)
        libGLdispatch.so.0 => /lib/x86_64-linux-gnu/libGLdispatch.so.0 (0x00007ffb91c46000)
        libGLX.so.0 => /lib/x86_64-linux-gnu/libGLX.so.0 (0x00007ffb91c13000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ffb92a7a000)
        libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x00007ffb91be9000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ffb91be4000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ffb91bc1000)
        libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x00007ffb91bbc000)
        libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007ffb91bb4000)
        libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007ffb91b9a000)

没有未定义的函数。

用file命令查看一下:

$ file HUDDrawingIntegrationExample_linux64_so.so 
HUDDrawingIntegrationExample_linux64_so.so: ELF 64-bit LSB pie executable, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=e19f9d860bd19b214e061697cbcf1655fdf03aec, stripped

Qt程序

基于Qt动态加载的程序代码详见:Qt动态加载VAPS XT编译生成的DLL文件

错误

这里指的是我遇到的错误。

Qt无法弹出窗口

现象就是点击打开文件按钮,应该弹出选择文件的窗口,但是界面卡死。实际上是弹出了窗口,但是这个窗口是透明的。

解决办法就是换个写法:

#ifdef Q_OS_WIN
    QString fileName = QFileDialog::getOpenFileName(this, QStringLiteral("选择动态库"), QString(),QString("*.dll\n*.so\n*"));
#endif

#ifdef Q_OS_LINUX
    QString fileName;
    QFileDialog filedialog;
    filedialog.setAcceptMode(QFileDialog::AcceptOpen);
    filedialog.setViewMode(QFileDialog::List);
    filedialog.setFileMode(QFileDialog::AnyFile);
    filedialog.setWindowTitle(tr("选择动态库"));
    filedialog.setDefaultSuffix("*.dll\n*.so\n*");
    filedialog.setOption(QFileDialog::DontUseNativeDialog);
    if(filedialog.exec()==  QDialog::Accepted )
    {
        QStringList filePaths = filedialog.selectedFiles();
        fileName =filePaths[0];
        qDebug() << fileName;
    }
#endif

加载完so后直接全屏

使用正常的步骤加载so后,so里面的内容直接占据了这个屏幕,但是位置没有变。

so

我们查看一下so文件是否正常。

ldd

可以看到有一个函数未定义,并且和Window有关。

查看一下函数相关信息:

$ c++filt _ZN11vxtPLWindowC2Ev
vxtPLWindow::vxtPLWindow()

这样就找到问题所在了。

测试

完整测试运行视频-B站

完整Qt代码在VAPS_XTdynamicload。测试用的so由官方示例编译而来。与Qt动态加载VAPS XT编译生成的DLL文件使用的是同一份代码。同时提供测试DLL/so文件。

赞赏

微信赞赏支付宝赞赏

Leave a Reply

您的电子邮箱地址不会被公开。 必填项已用*标注