文章目录
1.背景介绍
建议先查看之前的文章【CodeSys中调用C语言写的动态库】,了解如何创建一个能够被codesys调用的动态库。
假如想要在函数中使用Qt或者第三方库(比如opencv等),可以在其自动生成的makefile文件中设置好相应的参数。
2.修改makefile
修改后的makefile:
##############################################################################
# Copyright: Copyright CODESYS Development GmbH
# Program: Extension API for the Linux SL products
##############################################################################
#
# with this makefile you can influence the build of your component
#
#
# Hints:
# - the name of the *Itf.m4 file in this folder will be used as name of the shared object (and component name)
# - all C files in this folder will be compiled by default
#
# set versions of your shared object
# must be single digit, decimal
MAJORVER=0
MINORVER=1
# set a component version (must match your IEC library version)
# must be 4 bytes, hexadecimal
CMPVERSION=0x01000000
# set a component ID
# must be 2 bytes >= 0x2000 and hexadecimal and can be used to differentiate different components
CMPID=0x2000
# set your tools
DOS2UNIX = dos2unix
M4 = m4
# set a compiler
#CC = gcc
CC = g++
#INCLUDEPATH += /usr/include/opencv4
#LIBS += /usr/lib/x86_64-linux-gnu/libopencv_*.so #添加库
# add some compiler flags (with += )
#CFLAGS += -g
# add some include paths (with +=)
#INCLUDES += -I.
# add some linker flags (with += )
#LDFLAGS +=
# add some libraries that you might need (with += )
#LDLIBS += -lc
# 为了能够使用opencv而做的一些设置
INCLUDES += -I/usr/include/opencv4\
-I/usr/include/opencv4/opencv2
LDLIBS += /usr/lib/x86_64-linux-gnu/libopencv_*.so
# 必须要把自己创建的Qt静态库放前面,否则可能会报找不到某些函数的定义
# 这些函数的定义在后面的Qt动态库中,不知道为啥会出现这个情况
INCLUDES += -I/home/yong/Desktop/PLC/Library1/Qt/VisionLib
LDLIBS += /home/yong/Desktop/PLC/Library1/Qt/build-VisionLib-Desktop_Qt_5_15_2_GCC_64bit-Profile/libVisionLib.a
# #为了能够使用Qt而做的一些参数设置
INCLUDES += -I/opt/Qt/5.15.2/gcc_64/include\
-I/opt/Qt/5.15.2/gcc_64/include/QtCore\
-I/opt/Qt/5.15.2/gcc_64/mkspecs/linux-g++\
-I/opt/Qt/5.15.2/gcc_64/include/QtRemoteObjects
LDLIBS += /opt/Qt/5.15.2/gcc_64/lib/*.so
LDFLAGS += -Wl,-rpath,/opt/Qt/5.15.2/gcc_64/lib
# include of the SDK makefiles
SDKDIR=/home/yong/Desktop/PLC/ExtensionSDK
include ${SDKDIR}/makefile
主要是做了三个修改:
2.1.将编译器由c改成c++
2.2.使能opencv库
2.3.使能Qt库
这里特别注意一下这个:-Wl,-rpath,/opt/Qt/5.15.2/gcc_64/lib,这条语句是指定了运行时搜索库的路径,没有这句的话,虽然可以编译通过,但是运行时codesys就直接报错,无法下载了。可以看看这个资料的介绍【GCC/G++选项 -Wl,-rpath=】
我是如何知道需要写这个的?我是从QtCreator的编译输出看到的:
3.在代码中使用Qt库函数
这样操作之后,在include对应的头文件后,就可以在函数中使用opencv、Qt了。
4.注意事项
4.1.复杂Qt功能(预编译等)的处理
在实际的操作中发现,这种方式虽然可以调用Qt的一般函数、一般的类。但是假如想声明、实例化自己的Qt类(带属性、信号、槽),还是得用qmake(进行预编译)来操作才行,单单一个gcc还是比较难做到。
所以,在上面介绍的基础上,我叠加了一种可控性更好的方式:用QtCreator将所需函数编译成静态库,再在对应的c文件中调用。这样既可以利用到QtCreator的便利,又保证了去耦性,为将来的分工合作提供了基础。而且静态库会编译到最终的*.so文件中,就不用携带多个*.so了,符合codesys的要求。(或者也可以通过-Wl,-rpath来解决?)
4.2.多线程的问题
貌似codesys通过这种方式调用的c接口里面,不支持多线程。假如强行创建貌似会出问题,比如卡住或者别的的问题,还得再研究、实验一下。
4.3.QApplication的使用
通过这种方式使用QApplication时,需要加上一句代码,否则会导致codeSys runtime崩溃退出:
---
qputenv("QT_QPA_PLATFORM", "offscreen"); // 加这句
QApplication app(argc, argv);
---
主要原因是我们编写的这个库默认是在无UI界面的的环境中运行的,而QApplication默认是以xcb之类的界面输出的。通过设置QT_QPA_PLATFORM =offscreen就没问题了。
或者你也可以使用QCoreApplication,但是,假如用的是QCoreApplication,那么在QPainter的drawText时会引发崩溃(可能还有其他坑)。最好还是使用QApplication。