QT共享库的创建与调用(初级)(附:UI界面不能被改变的其中一个原因)
背景:
最近在做的一个项目其中一部分既是实现PC与下位机的USB通信。windows平台下已经完成,现需移植到linux平台下。
在linux系统中,通过一段时间的工作,设备已被配置成hid类(后续再详述),并以hidraw类设备节点存在于系统中"/dev/"下。上位机则成功在console中通过调用HIDAPI库来写入、读取hidraw设备节点信息(后续再详述),而进一步的图形界面则需由QT来完成。
hidraw设备介绍:
https://www.kernel.org/doc/Documentation/hid/hidraw.txt
HIDAPI介绍:
https://valelab.ucsf.edu/svn/3rdpartypublic/hidapi/hidapi-3a66d4e513/README.txt
现在的问题是,对于客户来说,他们并不需要"raw"设备节点,而是需要已被加工过、能被现成调用并能直观控制下位机的API。所以,制作QT共享库成为我的下一步工作。
共享库的好处在于,若共享库实现的功能需要更改,不需要大面积的更改主函数,只需更改共享库即可。
正文:
QT共享库的制作如下:
首先Create Project --> 选择Other Project --> C++ Library --> ... --> 默认选择QTCore(其他暂未研究)。
最后生成xxx_global.h, xxx.h, xxx.cpp文件。(xxx为项目名称。)
xxx_global.h文件里面宏定义了共享库的一些基本属性,
#include <QtCore/qglobal.h> #if defined(XXX_LIBRARY)
# defined XXX_EXPORT Q_DECL_EXPORT
#else
# defined XXX_EXPORT Q_DECL_IMPORT
#endif #endif // XXX_GLOBAL_H
点开看有没有很熟悉,DLL也有类似的代码段,具体作用暂未研究。
而我只在.h文件包含了HIDAPI头文件,并在其默认类里面声明了一个公共的USBOpen()函数及一些变量。然后在USBOpen()函数里调用了打开hidraw设备函数。
此时点击build(不是Run!)则可在build-xxx-Desktop-Debug文件夹中生成一个xxx.so共享库文件,和几个指向该.so库文件的软链接。
由于我需要使用HIDAPI的库所以还需要再做以下步骤,
在".pro"文件里添加
LIBS += -L .usr/local/lib/ -lhidapi-libusb (即共享库所在位置及共享库名称)
至此,共享库制作完毕。
调用共享库步骤如下:
新建一个新工程。
在".pro"文件添加
HEADERS += /home/aplex/usbapi (即共享库头文件所在位置) --->usbapi为我的共享库项目名称
LIB += -L /home/aplex/build-usbapi-Desktop-Debug/ -lusbapi(注意,此处应为项目名称,而不是共享库文件名称!)
在主函数中定义一个共享库内的类,并调用USBOpen()函数;build,成功!点击Run,然而见证奇迹的时刻并没有出现,取而代之的是一个错误提示:
error while loading shared libraries: xxx.so.1 can not open shared object file : No such file or directory。
借用一句大牛说过的话:有提示的错误那都不能算是错误!哈~
不过,为了解决这个错误也确实卡了我一点时间,后来查资料得知,原来run也有它的链接路径。解决办法既是:
点击QT左边工具栏的Projects --> RunSetting,找到Run Environment,点击Details --> 找到以下的值,没有则自行添加
Variable: LD_LIBRARY_PATH
Value:这个值一般已经有了默认库的路径,且每个路径以":"分隔开,在其末尾添加你的库所在路径即可,注意:在最后记得加上":"!
点击RUN,程序应该就可以正常运行并成功调用共享库了。
其他人如何调用此共享库:
首先,我们需要做的工作是,
1、将自己的共享库由Debug版本发布成Release-->在QT侧边栏'RUN'按钮之上有一个Desktop,改为'QT in PATH Release'; 接着点击'RUN'重新运行;
2、进入'xxx-build-desktop'文件夹内,将所有的'.so'文件(文件与软连接)使用 tar 命令打包成'.tar.bz2'文件(这么做的作用是,不至于在复制的时候,破坏这些文件的默认属性,可以做个实验,若是直接拷贝,则软链接文件会在拷贝后,直接变成普通文件)。
进入'xxx'文件内,将所有的'.h'文件使用 tar 命令打包成'.tar.bz2'文件。
接着,其他人若要调用此共享库,只需做如下步骤:
1、将两个'.tar.bz2'文件分别使用 tar 命令解压到'/usr/local/lib/', '/usr/local/include/'文件夹内;
2、更新库文件信息--> sudo ldconfig
3、在QT的'.pro'文件添加如下代码段
LIBS += -L .usr/local/lib/ -lxxx (xxx为共享库名称)
至此,即可在他人的电脑上调用我们自己的共享库了。
参考文章:
How to create a library with Qt and use it in an application
https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application
Linux下Qt创建和调用共享库文件.so
http://www.librehat.com/linux-qt-to-create-and-call-a-shared-library-so-file/
Building C++ shared libraries in Qt Creator (cross-platform)
https://blog.g3rt.nl/building-cpp-shared-libraries-qt-creator.html
附1:
无论怎么更改UI界面,点击'RUN'后,生成的UI却没有任何变化?
点击左侧的“Projects”,在Build Settings 内,将对应的选项进行更改。
附2:
以下为hidapi共享库调用出现的问题:
由于hidapi的调用需要root权限,直接点击run的话会无法打开hidraw设备。所以只能生成可执行文件,以sudo来运行。
前文已说明,主程序调用的是我自己的共享库,然后在共享库内调用HIDAPI库实现对hidraw设备的操作。现在使用sudo来打开主程序的可执行文件出现如下报错:
error while loading shared libraries: xxx.so.1: can not open shared object file:No such file or directory。
出现这种错误,一般解决办法即是更改 ".pro" 文件,告诉QT,共享库文件在哪。可是之前已经做过了,还是报错问题在哪呢?
做个测试,将主程序由调用我创建的共享库更改为直接调用HIDAPI共享库,并生成可执行文件,使用sudo,打开hidraw设备正常。说明还是共享库路径寻找出现了问题。
于是乎,我将.so文件拷贝到 /usr/local/lib/ 文件夹下,
并运行 sudo ldconfig;
再次运行之前生成的可执行文件,正常运行。所以说,即使更改了".pro"文件,生成的执行文件还是去系统默认的共享库存放位置查找,而不是按照".pro"文件的设定。
附3:
在使用ldconfig的过程中,出现了报错:
/sbin/ldconfig.real: /usr/local/lib/xxx.so.1 is not a symbolic link。
查找资料得知,xxx.so xxx.so.1 xxx.so.1.0 均是xxx.so.1.0.0的软链接,而我是从其他地方拷贝过来,软链接文件属性全部变成了普通文件属性,导致无法链接。
正确做法只需将.so拷贝进/usr/local/lib下,接着运行ldconfig即可完成链接。
记录地点:深圳WZ
记录时间:2015年12月7日 19:27:18
修正时间1:2015年12月22日 14:51:52
QT共享库的创建与调用(初级)(附:UI界面不能被改变的其中一个原因)的更多相关文章
- Linux C C语言库的创建和调用
C语言库的创建和调用 简介: 假如,你有一个庞大的工程,代码量达到数百兆甚至是数G,你经常会遇到好多重复或常用的地方.每次使用到这些地方时如果都重新写一份基本相同的代码,这当然可以,不过这样会大大地降 ...
- paip.c++ qt 共享库dll的建立
paip.c++ qt 共享库dll的建立 作者Attilax , EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.net/at ...
- Windows下静态库、动态库的创建和调用过程
静态库和动态库的使用包括两个方面,1是使用已有的库(调用过程),2是编写一个库供别人使用(创建过程).这里不讲述过多的原理,只说明如何编写,以及不正确编写时会遇见的问题. //注:本文先从简单到复杂, ...
- Qt 共享库(动态链接库)和静态链接库的创建及调用
前言: 编译器 Qt Creator, 系统环境 win7 64 位 1.创建共享库: 新建文件或项目->选择 Library 和 c++ 库->选择共享库->下一步(工程名为 sh ...
- 一个简单的C共享库的创建及Python调用此库的方法
/********************************************************************* * Author : Samson * Date ...
- Linux Qt动态库的创建和使用
一.创建动态库 编写一个共享库类,比如: //..base.h class Base : public QObject { Q_OBJECT public: ); void PrintLog(QStr ...
- Qt——动态库的创建和使用
一.动态库是什么 很多人写程序的人都见过.lib和.dll文件,对动态库也略有耳闻. 生成动态库后可以得到两个文件,后缀名分别是.lib以及.dll. 简而言之,.lib称为导入库,相当于头文件:.d ...
- 三、Android NDK编程预备之Java jni入门创建C/C++共享库
转自: http://www.eoeandroid.com/thread-264971-1-1.html 应网友回复,答应在两天前要出一篇创建C/C++共享库的,但由于清明节假期,跟朋友出去游玩,丢手 ...
- linux共享库加载
参考自: <<程序员的自我修养--链接.装载与库>> 第八章 Linux共享库的组织 以下截取部分内容 (这本书比较好的讲解了从程序的链接,装载,到运行) 共享库的兼容性 li ...
随机推荐
- Mouse.OverrideCursor
介绍: 获取和设置整个应用程序的光标,WPF父元素将覆盖所有子元素的光标. WPF设置控件的光标: WPF 中每个光标通过一个System.Windows.Input.Cursor表示, 获取Curs ...
- 【Beta】第一次任务发布
后端 整理以下5个环节的API文档:登录注册.收藏以及获取收藏.个人信息的获取以及更新.发送实验数据以获取PDF报告 验收条件:每个接口说明请求格式(请求方式,请求内容)和返回格式 例: 请求 方式: ...
- Python基本数据类型之str
一.创建 s = "morra" s = str("morra") #str()这种方法会自动找到str类里的_init_方法去执行 ------------- ...
- 我总结的js方面你可能不是特别清楚的小知识
!!将一个值方便快速转化为布尔值 console.log( !!window===true ); 不声明第三个变量实现交换 var a=1,b=2; a=[b,b=a][0];//执行完这句代码之后 ...
- BZOJ1933: [Shoi2007]Bookcase 书柜的尺寸
传送门 很容易看出来这是一道DP题,那么怎么设置状态就成了这道题的关键.本题有点特殊的地方是有两个维度的状态,而每个维度又有三个部分的参数,如果全部设置出来的话肯定会MLE.首先对书的厚度状态简化. ...
- centos搭建https协议的tomcat和apache服务器以及nginx服务器,mysql php
Apache HTTP Server(简称 Apache)是 Apache 软件基金会的一个开放源码的网页服务器,可以在大多数计算机操作系统中运行,由于其多平台和安全性被广泛使用,是最流行的 Web ...
- shell 中 &&和||的方法
Shell && 和 || shell 在执行某个命令的时候,会返回一个返回值,该返回值保存在 shell 变量 $? 中.当 $? == 0 时,表示执行成功:当 $? == 1 时 ...
- su su- sudo的区别
linux su命令参数及用法详解(linux切换用户命令) su的作用是变更为其它使用者的身份,超级用户除外,需要键入该使用者的密码 linux su 命令 建议大家切换用户的时候 使用 su ...
- webView(简单的浏览器)
#import "MJViewController.h" @interface MJViewController () <UISearchBarDelegate, UIWeb ...
- 转:遗传算法解决TSP问题
1.编码 这篇文章中遗传算法对TSP问题的解空间编码是十进制编码.如果有十个城市,编码可以如下: 0 1 2 3 4 5 6 7 8 9 这条编码代表着一条路径,先经过0,再经过1,依次下去. 2.选 ...