【OpcUA开发笔记 2】open62541在Linux下编译及Qt开发

前言

       在上一篇中,我们记录了在windows下通过CMake编译mingw版本的open62541,事实上是为了这一篇做铺垫,我们本次就在ubuntu下编译open62541,并通过Qt来调用它。

一、编译

1. 建立工程文件夹

   我在主目录中建立文件夹project,并将其设置为具有可读写权限,即cd到该文件夹,然后执行以下命令,这很关键,否则编译好的东西在关掉控制台的时候就消失白干了。

sudo chmod 777 ./

2. 下载源码

git clone https://github.com/open62541/open62541.git

3. 配置

       确保自己安装了g++,cmake之后,在open62541文件夹下建立build文件夹,cd到里面之后,执行以下代码,该选项用于生成open62541.h和open62541.c文件,当然还会生成open62541.a静态库文件,在这三个文件中,可以将.h和.c文件配合使用,也可以将.h和.a文件配合使用,前者是源码,后者是封装,但以下选项不打开为ON,这三者都不会生成。

cmake .. -D UA_ENABLE_AMALGAMATION=ON

 4. 编译

       在该目录下继续执行make:

make

        完成后,build\bin中只有open62541.a文件,如果想要继续编译例子,则需要先关闭UA_ENABLE_AMALGAMATION,再打开UA_BUILD_EXAMPLES,这两个编译时是互斥的。

5. 编译例子

        进入build文件夹,分别执行以下命令:

cmake .. -D UA_ENABLE_AMALGAMATION=OFF
cmake .. -D UA_BUILD_EXAMPLES=ON

然后执行 make,就会发现build\bin文件夹下多了个examples文件夹,你可以用他们试着玩一玩了。

二、用Qt调用open62541

        在windows下就用CMake生成VS版本比较好,一些windows依赖库也就自己加到工程里去了,如果要用Qt,注意以下几点:

1. Qt5建立Non-Qt-Project / C++ Plain Application工程,Qt6目前测试有问题;

2. 要用qMake,这样不用写cMake代码配置工程;

3. 我们将上一节生成的.h和.a文件放到open62541文件夹中并拷贝到工程目录下,在工程中添加库.a和.h文件(或者.c搭配.h文件,这种方式可以改一些配置。另外,在windows下基于mingw编译的.a静态库也能执行,不过要跨平台,在Linux下仍然需要重新编译.a静态库);

4. 如果有using namespace std,要放到 #include "open62541/open62541.h" 上面;

5. 需要在.pro中加入LIBS += -lpthread libwsock32 libws2_32

        本座在ubuntu下用Qt5.14.2调用open62541,跟以上类似,只是不需要第五步。以下给一个Server的例子,该例子来自于源码根目录下的examples\tutorial_server_variable.c,只是我们已经生成了open62541.h就可以干掉源码里的以下两句:

#include <open62541/plugin/log_stdout.h>
#include <open62541/server.h>

用一句 #include "open62541/open62541.h"代替就好了,免得有其他引用问题

//#include <open62541/plugin/log_stdout.h>
//#include <open62541/server.h>#include "open62541/open62541.h"
#include <stdio.h>static void
addVariable(UA_Server *server) {/* Define the attribute of the myInteger variable node */UA_VariableAttributes attr = UA_VariableAttributes_default;UA_Int32 myInteger = 42;UA_Variant_setScalar(&attr.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]);attr.description = UA_LOCALIZEDTEXT("en-US","the answer");attr.displayName = UA_LOCALIZEDTEXT("en-US","the answer");attr.dataType = UA_TYPES[UA_TYPES_INT32].typeId;attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE;/* Add the variable node to the information model */UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, "the.answer");UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, "the answer");UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);UA_Server_addVariableNode(server, myIntegerNodeId, parentNodeId,parentReferenceNodeId, myIntegerName,UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), attr, NULL, NULL);
}static void
addMatrixVariable(UA_Server *server) {UA_VariableAttributes attr = UA_VariableAttributes_default;attr.displayName = UA_LOCALIZEDTEXT("en-US", "Double Matrix");attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE;/* Set the variable value constraints */attr.dataType = UA_TYPES[UA_TYPES_DOUBLE].typeId;attr.valueRank = UA_VALUERANK_TWO_DIMENSIONS;UA_UInt32 arrayDims[2] = {2,2};attr.arrayDimensions = arrayDims;attr.arrayDimensionsSize = 2;/* Set the value. The array dimensions need to be the same for the value. */UA_Double zero[4] = {0.0, 0.0, 0.0, 0.0};UA_Variant_setArray(&attr.value, zero, 4, &UA_TYPES[UA_TYPES_DOUBLE]);attr.value.arrayDimensions = arrayDims;attr.value.arrayDimensionsSize = 2;UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, "double.matrix");UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, "double matrix");UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);UA_Server_addVariableNode(server, myIntegerNodeId, parentNodeId,parentReferenceNodeId, myIntegerName,UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),attr, NULL, NULL);
}/*** Now we change the value with the write service. This uses the same service* implementation that can also be reached over the network by an OPC UA client.*/static void
writeVariable(UA_Server *server) {UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, "the.answer");/* Write a different integer value */UA_Int32 myInteger = 43;UA_Variant myVar;UA_Variant_init(&myVar);UA_Variant_setScalar(&myVar, &myInteger, &UA_TYPES[UA_TYPES_INT32]);UA_Server_writeValue(server, myIntegerNodeId, myVar);/* Set the status code of the value to an error code. The function* UA_Server_write provides access to the raw service. The above* UA_Server_writeValue is syntactic sugar for writing a specific node* attribute with the write service. */UA_WriteValue wv;UA_WriteValue_init(&wv);wv.nodeId = myIntegerNodeId;wv.attributeId = UA_ATTRIBUTEID_VALUE;wv.value.status = UA_STATUSCODE_BADNOTCONNECTED;wv.value.hasStatus = true;UA_Server_write(server, &wv);/* Reset the variable to a good statuscode with a value */wv.value.hasStatus = false;wv.value.value = myVar;wv.value.hasValue = true;UA_Server_write(server, &wv);
}/*** Note how we initially set the DataType attribute of the variable node to the* NodeId of the Int32 data type. This forbids writing values that are not an* Int32. The following code shows how this consistency check is performed for* every write.*/static void
writeWrongVariable(UA_Server *server) {UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, "the.answer");/* Write a string */UA_String myString = UA_STRING("test");UA_Variant myVar;UA_Variant_init(&myVar);UA_Variant_setScalar(&myVar, &myString, &UA_TYPES[UA_TYPES_STRING]);UA_StatusCode retval = UA_Server_writeValue(server, myIntegerNodeId, myVar);printf("Writing a string returned statuscode %s\n", UA_StatusCode_name(retval));
}/** It follows the main server code, making use of the above definitions. */int main(void) {UA_Server *server = UA_Server_new();addVariable(server);addMatrixVariable(server);writeVariable(server);writeWrongVariable(server);UA_Server_runUntilInterrupt(server);UA_Server_delete(server);return 0;
}

至此,你发现已经可以运行了,下载一个UaExpert当做客户端来测一下吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/695978.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【前端素材】推荐优质后台管理系统APP Zina平台模板(附源码)

一、需求分析 当我们从多个层次来详细分析后台管理系统时&#xff0c;可以将其功能和定义进一步细分&#xff0c;以便更好地理解其在不同方面的作用和实际运作。 1. 功能层次 a. 用户管理功能&#xff1a; 用户注册和登录&#xff1a;管理用户账户的注册和登录过程。权限管…

用js-插入HTML元素

这段代码是一个有序列表&#xff08;ordered list&#xff09;&#xff0c;使用<ol>标签包裹起来。有序列表中的每一项由<li>标签表示。 在这个例子中&#xff0c;有三个列表项&#xff1a; 目录 1目录 2目录 3 这段代码会渲染成一个有序列表&#xff0c;显示为&am…

如何使用Docker部署开源Leanote蚂蚁笔记并发布个人博客至公网

最近&#xff0c;我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念&#xff0c;而且内容风趣幽默。我觉得它对大家可能会有所帮助&#xff0c;所以我在此分享。点击这里跳转到网站。 文章目录 1. 安装Docker2. Docker本地部署Leanote蚂蚁笔记3. 安装…

notepad++运行python闪一下就没啦

问题&#xff1a;Notepad直接快捷键运行Python代码,出现闪一下就没了 解决措施&#xff1a; ①点击菜单运行(Run) --> 运行(Run)弹出的对话框 ②把 cmd /k python "$(FULL_CURRENT_PATH)" & ECHO. & PAUSE & EXIT 粘贴进入这个对话框内 ③点击保存&a…

由面试题“Redis是否为单线程”引发的思考

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

代码随想录三刷day05

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣59. 螺旋矩阵 II二、力扣54. 螺旋矩阵 前言 相信大家有遇到过这种情况&#xff1a; 感觉题目的边界调节超多&#xff0c;一波接着一波的判断&#xff0…

边坡位移监测设备:守护工程安全的前沿科技

随着现代工程建设的飞速发展&#xff0c;边坡位移监测作为预防山体滑坡、泥石流等自然灾害的重要手段&#xff0c;日益受到人们的关注。边坡位移监测设备作为这一领域的关键技术&#xff0c;以其高精度、实时监测的特点&#xff0c;成为守护工程安全的重要武器。 一、边坡位移…

走深向实,数字化转型助力央国企高质量发展|爱分析报告

央国企数字化转型背景 1.1 央国企数字化转型驱动因素及目标 在政策、使命、内生需求的共同驱动下&#xff0c;数字化转型已成为央国企发展的必然选择。 政策指引&#xff1a;早在2020年&#xff0c;国资委发布了《关于加快推进国有企业数字化转型工作的通知》&#xff0c;对国…

信钰证券|印花税下降对股市的影响?印花税下降利好哪些板块?

投资者在买卖股票时&#xff0c;需求交纳一定的佣金费用、印花税和过户费用&#xff0c;其间印花税和过户费用&#xff0c;随着方针的变动&#xff0c;会进行相应的调整&#xff0c;那么&#xff0c;印花税下降对股市的影响&#xff1f;印花税下降利好哪些板块&#xff1f; 印花…

Android 系统定位和高德定位

文章目录 Android 系统定位和高德定位系统定位工具类封装LocationManager使用 高德定位封装高德地图使用 Android 系统定位和高德定位 系统定位 工具类 public class LocationUtils {public static final int REQUEST_LOCATION 0xa1;/*** 判断定位服务是否开启*/public sta…

(科目三)信息技术基础

1.信息与信息技术概述 1.1 信息的定义和表示 一、信息的定义&#xff1a; 信息就是通过语言、文字、图形/图像、声音、视频等传播的内容。 信息≠消息&#xff0c;信息就是消息的内核&#xff0c;消息是信息的外壳。 信息不是某种信号&#xff0c;也不等同于知识。 数据&…

算法沉淀——穷举、暴搜、深搜、回溯、剪枝综合练习三(leetcode真题剖析)

算法沉淀——穷举、暴搜、深搜、回溯、剪枝综合练习三 01.字母大小写全排列02.优美的排列03.N 皇后04.有效的数独 01.字母大小写全排列 题目链接&#xff1a;https://leetcode.cn/problems/letter-case-permutation/ 给定一个字符串 s &#xff0c;通过将字符串 s 中的每个字…

设计模式--原型模式和建造者模式

原型模式 原型模式&#xff08;Prototype Pattern&#xff09;是指原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些这些原型创建新的对象&#xff0c;属于创建型模式。&#xff08;对不通过new关键字&#xff0c;而是通过对象拷贝来实现创建对象的模式称为原型模式&a…

【达梦数据库】查看pesg回滚段信息的视图和SQL

一些达梦回滚段是使用情况的查询SQL&#xff0c;供排查“回滚记录版本太旧&#xff0c;无法获取用户记录” 等类似问题时使用 视图名说明主库备库v$pseg_items显示回滚系统中当前回滚项信息&#xff08;回滚线程的工作信息&#xff09;总行数WORKER_THREADS1查询 no rowsv$pseg…

安装Windows Server 2025 搭建免费云桌面系统

介绍 Windows Server 2025 为 Hyper-V 带来了多项增强功能和新的存储特性&#xff0c;主要用于优化虚拟机的运行体验。这些新特性涵盖 GPU 虚拟化、新的 ReFS 去重功能&#xff0c;以及在非 AD 域的集群上进行虚拟机实时迁移。 云桌面方案的用户最关心的GPU-P的技术也将在Win…

VMware虚拟机文件夹共享失效

问题现象 今天开启虚拟机的时候就看到这个&#xff0c;感觉又要有不好的事情发生了。 果不其然&#xff0c;开机之后弹出这个&#xff0c;我当时还没意识到这个dll文件会对我的正常使用产生什么样的影响。 然后就发现文件根本拷贝不进去虚拟机里面&#xff0c;连虚拟机里面的共…

缓存篇—缓存雪崩、缓存击穿、缓存穿透

缓存异常会面临的三个问题&#xff1a;缓存雪崩、击穿和穿透。 其中&#xff0c;缓存雪崩和缓存击穿主要原因是数据不在缓存中&#xff0c;而导致大量请求访问了数据库&#xff0c;数据库压力骤增&#xff0c;容易引发一系列连锁反应&#xff0c;导致系统奔溃。不过&#xff0…

petalinux_zynq7 驱动DAC以及ADC模块之三:实现C语言API并编译出库被python调用

前文&#xff1a; petalinux_zynq7 C语言驱动DAC以及ADC模块之一&#xff1a;建立IPhttps://blog.csdn.net/qq_27158179/article/details/136234296petalinux_zynq7 C语言驱动DAC以及ADC模块之二&#xff1a;petalinuxhttps://blog.csdn.net/qq_27158179/article/details/1362…

跨界计算与控制,强化显控和UI, 君正MPU再添新旗舰--Ingenic MPU X2600隆重发布

近日&#xff0c;北京君正隆重发布MPU芯片新产品X2600。该产品以商业和工业应用的数个细分领域为重点目标市场&#xff0c;兼顾通用处理器应用需求。无论从CPU结构的设计&#xff0c;还是专门控制器和接口的配备&#xff0c;都体现了北京君正MPU团队“技术路线上追求自主跨界&a…

力扣101 对称二叉树 Java版本

文章目录 题目描述递归解法非递归解法 题目描述 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出…