2

我正在尝试在一个请求中编写多个节点,但是我没有找到任何有关如何执行此操作的文档或示例,每次我发现有关该问题的任何内容时,都会写入一个节点。根据我对 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 库中触发了一个异常: 在此处输入图像描述

另外,我知道我可以专门将多个值写入数组,即使在这个可以解决我的问题的特定示例中,这不是我的意思,这个示例只是为了简化我的问题。假设我有一个多类型的结构,我想写入它,所有这些都在一个请求中。我很感激任何帮助!

4

1 回答 1

2

首先,这很糟糕:


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只能删除堆上的东西而不是堆栈上的东西,因此它失败了。

你现在有两个选择:

  1. 如果您仍然想使用堆栈技巧 UA_clear 认为变量为空:
wReq.nodesToWrite = NULL;
wReq.nodesToWriteSize = 0;
UA_clear(&wReq);
  1. 将节点放在堆上:而不是 UA_WriteValue my_nodes[3];使用类似的东西UA_WriteValue *my_nodes = (UA_WriteValue*)UA_malloc(sizeof(UA_WriteValue)*3);

此外,我强烈建议您使用 valgrind 或 clang memory sanitizer 来避免所有这些内存问题。

于 2020-05-08T06:32:16.933 回答