[英]How to write multiple nodes with OPC-UA at once using open62541?
I am attempting to write multiple nodes in a single request, however I have not found any documentation or examples on how to do that, every time I find anything regarding the issue, a single node is written.我正在尝试在一个请求中编写多个节点,但是我没有找到任何有关如何执行此操作的文档或示例,每次我发现有关该问题的任何内容时,都会写入一个节点。 Based on my understanding of the open62541 library (which is not much), I've attempted to do this like so:
根据我对 open62541 库(不多)的理解,我尝试这样做:
void Write_from_3_to_5_piece_queue() {
char NodeID[128];
char NodeID_backup[128];
char aux[3];
bool bool_to_write = false;
strcpy(NodeID_backup, _BaseNodeID);
strcat(NodeID_backup, "POU.AT2.piece_queue["); // this is where I want to write, I need only to append the array index in which to write
UA_WriteRequest wReq;
UA_WriteValue my_nodes[3]; // this is where I start to make things up, I'm not sure this is the correct way to do it
my_nodes[0] = *UA_WriteValue_new();
my_nodes[1] = *UA_WriteValue_new();
my_nodes[2] = *UA_WriteValue_new();
strcpy(NodeID, NodeID_backup);
strcat(NodeID, "3]"); //append third index of array (will write to piece_queue[3])
my_nodes[0].nodeId = UA_NODEID_STRING_ALLOC(_nodeIndex, NodeID);
my_nodes[0].attributeId = UA_ATTRIBUTEID_VALUE;
my_nodes[0].value.hasValue = true;
my_nodes[0].value.value.type = &UA_TYPES[UA_TYPES_BOOLEAN];
my_nodes[0].value.value.storageType = UA_VARIANT_DATA_NODELETE;
my_nodes[0].value.value.data = &bool_to_write;
strcpy(NodeID, NodeID_backup);
strcat(NodeID, "4]");
my_nodes[1].nodeId = UA_NODEID_STRING_ALLOC(_nodeIndex, NodeID);
my_nodes[1].attributeId = UA_ATTRIBUTEID_VALUE;
my_nodes[1].value.hasValue = true;
my_nodes[1].value.value.type = &UA_TYPES[UA_TYPES_BOOLEAN];
my_nodes[1].value.value.storageType = UA_VARIANT_DATA_NODELETE;
my_nodes[1].value.value.data = &bool_to_write;
strcpy(NodeID, NodeID_backup);
strcat(NodeID, "5]");
my_nodes[2].nodeId = UA_NODEID_STRING_ALLOC(_nodeIndex, NodeID);
my_nodes[2].attributeId = UA_ATTRIBUTEID_VALUE;
my_nodes[2].value.hasValue = true;
my_nodes[2].value.value.type = &UA_TYPES[UA_TYPES_BOOLEAN];
my_nodes[2].value.value.storageType = UA_VARIANT_DATA_NODELETE;
my_nodes[2].value.value.data = &bool_to_write;
UA_WriteRequest_init(&wReq);
wReq.nodesToWrite = my_nodes;
wReq.nodesToWriteSize = 3;
UA_WriteResponse wResp = UA_Client_Service_write(_client, wReq);
UA_WriteResponse_clear(&wResp);
UA_WriteRequest_clear(&wReq);
return;
}
At first I didn't have much hope that this would work, but it turns out this actually writes the values that I wish.起初我并没有太大希望这会起作用,但事实证明这实际上写入了我希望的值。 The problem is that on
UA_WriteRequest_clear(&wReq);
问题在于
UA_WriteRequest_clear(&wReq);
I trigger an exception in the open62541 library:我在 open62541 库中触发了一个异常:
Also, I know I can write multiple values to arrays specifically, even though in this particular example that would fix my issue, that's not what I mean to do, this example is just to simplify my problem.另外,我知道我可以专门向 arrays 写入多个值,即使在这个可以解决我的问题的特定示例中,这不是我的意思,这个示例只是为了简化我的问题。 Just suppose I have a multi-type structure and I want to write to it, all in a single request.
假设我有一个多类型的结构,我想写入它,所有这些都在一个请求中。 I appreciate any help!
我很感激任何帮助!
First of all, this is bad:首先,这很糟糕:
UA_WriteValue my_nodes[3];
my_nodes[0] = *UA_WriteValue_new();
my_nodes[1] = *UA_WriteValue_new();
my_nodes[2] = *UA_WriteValue_new();
my_nodes is already created on the stack, and then you are copying the content of a new object into it by dereferencing. my_nodes 已在堆栈上创建,然后您通过取消引用将新 object 的内容复制到其中。 This definitely leads to memory leaks.
这肯定会导致 memory 泄漏。 You probably want to use
UA_WriteValue_init()
instead.您可能想改用
UA_WriteValue_init()
。 Never ever dereference the return value of a new()
function.永远不要取消引用
new()
function 的返回值。
Let's go bottom up:让我们 go 自下而上:
UA_WriteRequest_clear(&wReq)
is recursively freeing all content of the wReq
steucture. UA_WriteRequest_clear(&wReq)
递归地释放wReq
结构的所有内容。 This means that it will also call: UA_Array_delete(wReq.nodesToWrite, wReq.nodesToWriteSize, ...)
which in turn calls UA_free(wReq.nodesToWrite)
这意味着它还将调用:
UA_Array_delete(wReq.nodesToWrite, wReq.nodesToWriteSize, ...)
进而调用UA_free(wReq.nodesToWrite)
And you have: wReq.nodesToWrite = my_nodes;
你有:
wReq.nodesToWrite = my_nodes;
with UA_WriteValue my_nodes[3];
使用
UA_WriteValue my_nodes[3];
This means that you are assigning a variable, which lives on the stack to a pointer, and later this pointer is freed.这意味着您正在将一个位于堆栈中的变量分配给一个指针,然后该指针被释放。
free
can only delete stuff which is on the heap and not stack, and therefore it fails. free
只能删除堆上而不是堆栈上的东西,因此它失败了。
You have two options now:你现在有两个选择:
wReq.nodesToWrite = NULL;
wReq.nodesToWriteSize = 0;
UA_clear(&wReq);
UA_WriteValue my_nodes[3];
UA_WriteValue my_nodes[3];
use Something like UA_WriteValue *my_nodes = (UA_WriteValue*)UA_malloc(sizeof(UA_WriteValue)*3);
UA_WriteValue *my_nodes = (UA_WriteValue*)UA_malloc(sizeof(UA_WriteValue)*3);
Also I strongly recommend that you either use valgrind or clang memory sanitizer to avoid all these memory issues.此外,我强烈建议您使用 valgrind 或 clang memory 消毒剂来避免所有这些 memory 问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.