我试图在单个请求中编写多个节点,但是,我没有找到任何有关如何执行此操作的文档或示例,每当我发现与该问题有关的任何内容时,都会写入一个节点。基于对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;
}
起初,我不太希望这能奏效,但事实证明,这实际上写出了我想要的值。问题是在
UA_WriteRequest_clear(&wReq);
上,我在open62541库中触发了一个异常:另外,我知道我可以将多个值专门写入数组,即使在这个可以解决问题的特定示例中,这也不是我要做的事情,该示例只是为了简化我的问题。只是假设我有一个多类型的结构,并且想在单个请求中编写它。感谢您的帮助!
最佳答案
首先,这很不好:
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已经在堆栈上创建,然后通过取消引用将新对象的内容复制到其中。这肯定会导致内存泄漏。您可能想改用
UA_WriteValue_init()
。永远不要取消引用
new()
函数的返回值。让我们自下而上:
UA_WriteRequest_clear(&wReq)
递归释放wReq
结构的所有内容。这意味着它还将调用:
UA_Array_delete(wReq.nodesToWrite, wReq.nodesToWriteSize, ...)
依次调用UA_free(wReq.nodesToWrite)
你有:
wReq.nodesToWrite = my_nodes;
与UA_WriteValue my_nodes[3];
这意味着您要分配一个变量,该变量驻留在堆栈中并指向一个指针,然后释放该指针。
free
只能删除堆中的内容,不能删除堆栈中的内容,因此失败。您现在有两个选择:
wReq.nodesToWrite = NULL;
wReq.nodesToWriteSize = 0;
UA_clear(&wReq);
代替
UA_WriteValue my_nodes[3];
使用类似于UA_WriteValue *my_nodes = (UA_WriteValue*)UA_malloc(sizeof(UA_WriteValue)*3);
我也强烈建议您使用valgrind或clang内存清理程序来避免所有这些内存问题。
关于c++ - 如何使用open62541一次用OPC-UA编写多个节点?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61669378/