使用 QT 在 ubuntu 上的共享库(无主库)中运行应用程序

Posted

技术标签:

【中文标题】使用 QT 在 ubuntu 上的共享库(无主库)中运行应用程序【英文标题】:runing an QApplication in a shared library (without main) on ubuntu using QT 【发布时间】:2017-09-29 10:26:20 【问题描述】:

我需要编写一个共享库(将静态库连接到软件)。静态库是一个基于 QWizardPage 的项目,旨在在软件运行时制作未来的界面。

静态库: .pro

#-------------------------------------------------
#
# Project created by QtCreator 2017-09-29T01:12:06
#
#-------------------------------------------------

QT       += widgets

TARGET = FutureInterface
TEMPLATE = lib
CONFIG += staticlib

SOURCES += futureinterface.cpp

HEADERS += futureinterface.h
unix 
    target.path = /usr/lib
    INSTALLS += target


FORMS += \
    futureinterface.ui

.h

#ifndef FUTUREINTERFACE_H
#define FUTUREINTERFACE_H

#include <QWizardPage>

namespace Ui 
    class FutureInterface;


class FutureInterface : public QWizardPage

    Q_OBJECT

public:
    explicit FutureInterface(QWidget *parent = 0);
    ~FutureInterface();

private slots:
    void on_pushButton_clicked();

private:
    Ui::FutureInterface *ui;
;

#endif // FUTUREINTERFACE_H

.cpp

#include "futureinterface.h"
#include "ui_futureinterface.h"

FutureInterface::FutureInterface(QWidget *parent) :
    QWizardPage(parent),
    ui(new Ui::FutureInterface)

    ui->setupUi(this);


FutureInterface::~FutureInterface()

    delete ui;


void FutureInterface::on_pushButton_clicked()



我需要在以下函数中在我的共享库中运行 FutureInterface。


共享库的全部代码:

#include "v_repExtQuadRotor.h"
#include "scriptFunctionData.h"
#include <iostream>
#include "v_repLib.h"
#include <eigen3/Eigen/Dense>
#include "FutureInterface/futureinterface.h"
#include <QApplication>

typedef Eigen::Matrix<float, 7, 1> vector7f;
typedef Eigen::Matrix<float, 6, 1> vector6f;
typedef Eigen::Matrix<float, 4, 1> vector4f;
typedef Eigen::Matrix<float, 6, 6> matrix66f;

#ifdef _WIN32
    #ifdef QT_COMPIL
        #include <direct.h>
    #else
        #include <shlwapi.h>
        #pragma comment(lib, "Shlwapi.lib")
    #endif
#endif /* _WIN32 */
#if defined (__linux) || defined (__APPLE__)
    #include <unistd.h>
    #define WIN_AFX_MANAGE_STATE
#endif /* __linux || __APPLE__ */

#define CONCAT(x,y,z) x y z
#define strConCat(x,y,z)    CONCAT(x,y,z)

#define PLUGIN_NAME "QuadRotor"

LIBRARY vrepLib;

struct sQuadRotor

    int motorHandles[4];
    vector4f jointVelocity;
    vector6f sensorData;
;
std::vector<sQuadRotor> allQuadRotors;
void app()
    int argc = 1;
    char appname[] = "App";
    char* argv[] = appname, NULL;
    QApplication a(argc, argv);
    FutureInterface w;
    w.show();
    int i=a.exec();


// --------------------------------------------------------------------------------------
// simExtQuadRotor_create
// --------------------------------------------------------------------------------------
#define LUA_CREATE_QRCOMMAND "simExtQuadRotor_create"

const int inArgs_QRCREATE[]=

    1,
    sim_script_arg_int32|sim_script_arg_table,4,
;

void LUA_CREATE_QRCALLBACK(SScriptCallBack* cb)

    allQuadRotors.clear();
    CScriptFunctionData D;
    if (D.readDataFromStack(cb->stackID,inArgs_QRCREATE,inArgs_QRCREATE[0],LUA_CREATE_QRCOMMAND))
    
        std::vector<CScriptFunctionDataItem>* inData=D.getInDataPtr();
        sQuadRotor QuadRotor;
        for(int n=0;n<4;n++)
            QuadRotor.motorHandles[n]=inData->at(0).int32Data[n];
        
        QuadRotor.jointVelocity<<Eigen::VectorXf::Zero(4);
        QuadRotor.sensorData<<Eigen::VectorXf::Zero(6);
        allQuadRotors.push_back(QuadRotor);
    
    D.pushOutData(CScriptFunctionDataItem(1));
    D.writeDataToStack(cb->stackID);


// --------------------------------------------------------------------------------------



VREP_DLLEXPORT unsigned char v_repStart(void* reservedPointer,int reservedInt)
 // This is called just once, at the start of V-REP.
    // Dynamically load and bind V-REP functions:
    char curDirAndFile[1024];
#ifdef _WIN32
    #ifdef QT_COMPIL
        _getcwd(curDirAndFile, sizeof(curDirAndFile));
    #else
        GetModuleFileName(NULL,curDirAndFile,1023);
        PathRemoveFileSpec(curDirAndFile);
    #endif
#elif defined (__linux) || defined (__APPLE__)
    getcwd(curDirAndFile, sizeof(curDirAndFile));
#endif
    std::string currentDirAndPath(curDirAndFile);
    std::string temp(currentDirAndPath);

#ifdef _WIN32
    temp+="\\v_rep.dll";
#elif defined (__linux)
    temp+="/libv_rep.so";
#elif defined (__APPLE__)
    temp+="/libv_rep.dylib";
#endif /* __linux || __APPLE__ */

    vrepLib=loadVrepLibrary(temp.c_str());
    if (vrepLib==NULL)
    
        std::cout << "Error, could not find or correctly load v_rep.dll. Cannot start 'QuadRotor' plugin.\n";
        return(0); // Means error, V-REP will unload this plugin
    
    if (getVrepProcAddresses(vrepLib)==0)
    
        std::cout << "Error, could not find all required functions in v_rep.dll. Cannot start 'QuadRotor' plugin.\n";
        unloadVrepLibrary(vrepLib);
        return(0); // Means error, V-REP will unload this plugin
    

    // Check the V-REP version:
    int vrepVer;
    simGetIntegerParameter(sim_intparam_program_version,&vrepVer);
    if (vrepVer<30200) // if V-REP version is smaller than 3.02.00
    
        std::cout << "Sorry, your V-REP copy is somewhat old, V-REP 3.2.0 or higher is required. Cannot start 'QuadRotor' plugin.\n";
        unloadVrepLibrary(vrepLib);
        return(0); // Means error, V-REP will unload this plugin
    

    // Register 4 new Lua commands:
    simRegisterScriptCallbackFunction(strConCat(LUA_CREATE_QRCOMMAND,"@",PLUGIN_NAME),strConCat("number QuadRotorHandle=",LUA_CREATE_QRCOMMAND,"(table_4 JointHandles)"),LUA_CREATE_QRCALLBACK);

    return(8); // initialization went fine, we return the version number of this plugin (can be queried with simGetModuleName)
    // version 1 was for V-REP versions before V-REP 2.5.12
    // version 2 was for V-REP versions before V-REP 2.6.0
    // version 5 was for V-REP versions before V-REP 3.1.0 
    // version 6 is for V-REP versions after V-REP 3.1.3
    // version 7 is for V-REP versions after V-REP 3.2.0 (completely rewritten)
    // version 8 is for V-REP versions after V-REP 3.3.0 (using stacks for data exchange with scripts)


VREP_DLLEXPORT void v_repEnd()
 // This is called just once, at the end of V-REP
    unloadVrepLibrary(vrepLib); // release the library


VREP_DLLEXPORT void* v_repMessage(int message,int* auxiliaryData,void* customData,int* replyData)
 // This is called quite often. Just watch out for messages/events you want to handle
    // This function should not generate any error messages:
    int errorModeSaved;
    simGetIntegerParameter(sim_intparam_error_report_mode,&errorModeSaved);
    simSetIntegerParameter(sim_intparam_error_report_mode,sim_api_errormessage_ignore);
    void* retVal=NULL;
    if (message==sim_message_eventcallback_modulehandle)
    
        if ( (customData==NULL)||(std::string("QuadRotor").compare((char*)customData)==0) ) // is the command also meant for QuadRotor?
        
          if(allQuadRotors.size()>0)
              //controller***********************************************************************************
              app();

          
        
    

    if (message==sim_message_eventcallback_simulationended)
     // simulation ended. Destroy all QuadRotor instances:
        allQuadRotors.clear();
    

    simSetIntegerParameter(sim_intparam_error_report_mode,errorModeSaved); // restore previous settings
    return(retVal);

我需要安装一些软件包或依赖项吗?因为,现在我的软件将无法加载共享库。似乎该软件无法找到 QWizardPage 依赖项。你能告诉我我搞砸了什么吗?非常感谢

好像是因为我使用QApplication在共享库中执行静态库导致软件无法加载?

在共享库中使用 QApplication 有问题吗?我应该做点别的吗?

【问题讨论】:

尝试使用v_repMessage函数在文件中添加#include &lt;QApplication&gt; 非常感谢,解决了问题,我完美构建了共享库。 我需要安装一些包还是一些依赖项。因为,现在我的软件将无法加载共享库。似乎该软件无法找到 QWizardPage 依赖项。你能告诉我我搞砸了什么吗?非常感谢 【参考方案1】:

问题是因为 QT 的版本。该软件是在不同的 QT 版本中实现的,与我尝试在其中实现代码的版本形成对比。

【讨论】:

以上是关于使用 QT 在 ubuntu 上的共享库(无主库)中运行应用程序的主要内容,如果未能解决你的问题,请参考以下文章

ubuntu下借助qt creator创建属于自己的共享库

使用共享库在 Ubuntu 上部署 Qt 应用程序二进制文件

如何在 Ubuntu 14.04 上的 QT creator 中使用 Boost 库

Qt5 (Ubuntu 16.04) 上的 QCA 链接库出错

如何使用应用程序部署 Qt 库?

Qt系列文章之三十八(基于QWidget 创建和使用动态dll共享库)