使用 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 <QApplication>
行
非常感谢,解决了问题,我完美构建了共享库。
我需要安装一些包还是一些依赖项。因为,现在我的软件将无法加载共享库。似乎该软件无法找到 QWizardPage 依赖项。你能告诉我我搞砸了什么吗?非常感谢
【参考方案1】:
问题是因为 QT 的版本。该软件是在不同的 QT 版本中实现的,与我尝试在其中实现代码的版本形成对比。
【讨论】:
以上是关于使用 QT 在 ubuntu 上的共享库(无主库)中运行应用程序的主要内容,如果未能解决你的问题,请参考以下文章
使用共享库在 Ubuntu 上部署 Qt 应用程序二进制文件
如何在 Ubuntu 14.04 上的 QT creator 中使用 Boost 库