当前页面访问量: 59

Windows下Qt动态加载VAPS XT编译生成的DLL文件

Posted by

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

开发环境

软件 版本
OS Windows 10 20H2
VS 2013
Qt 5.10.1
编译器 MSVC2013_64bit for Qt 5.10.1
VAPS XT 4.2.1

首先先准备一个VAPS XT编译生成的DLL文件,使用VAPS编译就可以了。

创建一个空白的QWidget项目。

在*.pro文件中添加:

有的操作系统没有GLU32等等链接库,所以就直接加上。

在*.ui文件中添加QWidget窗口,至少一个用于显示效果。

这是我的界面:

ui

QOpenGLWidget类

在FFmpeg系列和OpenGL系列中有提及Qt+OpenGL的开发,本文简单介绍一下。

首先创建一个类,继承QOpenGLWidget和QOpenGLFunctions。

有三个必须实现的虚函数:

protected:
    void initializeGL() override;
    void paintGL() override;
    void resizeGL(int width, int height) override;

initializeGL用于初始化,PaintGL用于实时绘图,resizeGL用于调整界面大小。三个函数由基类直接调用。

首先添加头文件:

#include "GL/gl.h"

#include "./include/vxtRTDrawingIntegrationI.h"
#include "c:\Presagis\VAPS_XT_4_2_1\src\Ports\OS\win32\include\vxtPLBasicTypes.h"

定义接口

typedef vxtRTDrawingIntegrationI* (*fCreateTopIntegrator)();

官方示例就是这样写的。

创建接口对象:

vxtRTDrawingIntegrationI*  m_pDrawingIntegration = NULL;

初始化

//初始化opengl窗口部件
void myopenGL::initializeGL()
{
    initializeOpenGLFunctions();
    glClearColor(0.0,0.0,0.0,1.0);
    glShadeModel(GL_SMOOTH);

    glClearDepth(1.0);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
}

就是常用的清空缓冲区、设置背景色等等。

绘图

//绘制opengl窗口
void myopenGL::paintGL()
{
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    //绘制操作:
    glMatrixMode ( GL_PROJECTION );
    glLoadIdentity();
    glOrtho ( 0, this->width(), 0, this->height(), -1, 1 );
    glMatrixMode ( GL_MODELVIEW );
    glLoadIdentity();

    if (NULL != m_pDrawingIntegration){
        m_pDrawingIntegration->vExecuteIteration();
    }

    glFlush();
    update();
}

和普通的OpenGL程序一样,不过最重要的是调用接口通知VAPS XT DLL进行绘图。

调整大小

//处理窗口大小
void myopenGL::resizeGL(int width, int height)
{
    glMatrixMode ( GL_PROJECTION );
    glLoadIdentity();
    glOrtho ( 0, this->width(), 0, this->height(), -1, 1 );
    glMatrixMode ( GL_MODELVIEW );
    glLoadIdentity();

   if (NULL != m_pDrawingIntegration){
      m_pDrawingIntegration->vSetSize(0, width, height);
   }

   glViewport(0, 0, this->width(), this->height());                  //重置模型观察矩阵
}

加载DLL

使用QLibrary来加载DLL,解析DLL的函数列表,设置调用参数,然后初始化接口。

代码为:

void myopenGL::loadDll(QString fileName)
{
    UnLoadDll();

    lib=new QLibrary(fileName);
    if(lib->load()){
        fCreateTopIntegrator fun = (fCreateTopIntegrator)lib->resolve("vxtGetDrawingIntegrationI");
        if(fun){
            m_pDrawingIntegration = fun();
            if(NULL != m_pDrawingIntegration){
                const char *argv[4];
                argv[0] = "VAPSXT.exe";
                argv[1] = "-alwaysdraw";
                argv[2] = "-fit";
                argv[3] = "-displayupdaterate";

                const int size = sizeof(argv) / sizeof(argv[0]);
                if(VXT_TRUE == m_pDrawingIntegration->vInit(size, (char **)argv, VXT_FALSE)){
                    // The following line sets the VAPS XT drawing area to have the full extent of the MFC Window.
                    m_pDrawingIntegration->vSetSize(0, this->width(), this->height());
                }else{
                    // The following line sets the VAPS XT drawing area to have the full extent of the MFC Window.
                    m_pDrawingIntegration->vSetSize(0, this->width(), this->height());
                    qDebug() << "Cannot initialize the vxtRTDrawingIntegrationI";
                }
            }else{
                qDebug() << "m_pDrawingIntegration is NULL";
            }
        }else{
            qDebug() << "Get fun Error";
        }
    }else{
        qDebug() << "Load library Error";
    }
}

说明一下argv参数。

VAPS参考文档中提供了以下几个参数:
– [-width ]: 指定窗口的宽度(像素值)
– [-height ]: 指定窗口的高度(像素值)
– [-xpos ]: 指定窗口的X位置(像素值)
– [-ypos ]: 指定窗口的Y位置(像素值)
– [-noborder]: 移除窗口的黑色边框
– [-center]: 将图像界面移至窗口中心位置
– [-fit]: 将图像界面缩放并放置到适应窗口
– [-bottomleftwindoworigin]: 设置屏幕的左下角作为窗口的起点
– [-fulldraw |: (默认)当发生变化时才绘制整个框架(frame)
– [-alwaysdraw]: 总是绘制整个框架(frame)即使没有什么东西发生变化
– [-displaylist]: 使用显示列表(display list)优化
– [-truetypefontpath ]: 设置字体路径

VAPSXT有自动执行程序的脚本,脚本中也是使用这些参数。

取消加载

void myopenGL::UnLoadDll()
{
    if(lib!=NULL){
        if(VXT_NULL != m_pDrawingIntegration){
            m_pDrawingIntegration->vClose();
            m_pDrawingIntegration = VXT_NULL;

            lib->unload();
            lib = NULL;
        }
    }
}

调用接口关闭,重置指针。

测试

编译运行,

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

赞赏

微信赞赏支付宝赞赏

Leave a Reply

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