Python 解释的 C++ 字节数组 (struct)

Dan*_*iel 3 c++ python arrays struct

我正在尝试将 C++ 结构从我的 arduino 传递到我的树莓派。我有一个看起来像这样的结构:

struct node_status
{
  char *node_type = "incubator";
  char *sub_type;          // set the type of incubator
  int sub_type_id;
  bool sleep = false;         // set to sleep
  int check_in_time = 1000;   // set check in time
  bool LOCK = false;      // set if admin control is true/false
} nodeStatus;
Run Code Online (Sandbox Code Playgroud)

我尝试使用名为 struct 的 python 模块

from struct import *

                print("Rcvd Node Status msg from 0{:o}".format(header.from_node))
                print("node_type: {}".format(unpack("10s",payload[0]))) #node_type
                node_type = unpack("10s",payload[0])
                print("sub_type: {}".format(unpack("10s",payload[1]), header.from_node))    #sub_type
                sub_type = unpack("10s",payload[1])
                print("sub_type_id: {}".format(unpack("b",payload[2])))
                sub_type_id = unpack("b",payload[2])
                print("sleep: {}".format(unpack("?",payload)[3]))   #sleep
                sleep = unpack("?",payload[3])
                print("check_in_time: {}".format(unpack("l",payload[4])))   #check_in_time
                check_in_time = unpack("l",payload[4])
                print("Lock: {}".format(unpack("?",payload[5])))    #LOCK
                Lock = unpack("?",payload[5])
Run Code Online (Sandbox Code Playgroud)

但我运气不佳。我什至只考虑使用 ctypes 模块,但似乎没有去任何地方..

from ctypes import *

class interpret_nodes_status(Structure):
    _fields_ = [('node_type',c_char_p),
                ('sub_type',c_char_p),
                ('sub_type_id',c_int),
                ('sleep',c_bool),
                (check_in_time',c_int),
                ('LOCK',c_bool)]

nodestatus = translate_nodes_status(payload)
Run Code Online (Sandbox Code Playgroud)

但这只是给了我一个错误

TypeError: bytes or integer address expected instead of bytearray instance
Run Code Online (Sandbox Code Playgroud)

我能做什么?我哪里出错了?

编辑:

我正在使用来自的 RF24Mesh 库

https://github.com/nRF24/RF24Mesh

我发送消息的方式是这样的?

  RF24NetworkHeader header();

  if (!mesh.write(&nodeStatus, /*type*/ 126, sizeof(nodeStatus), /*to node*/ 000))
  { // Send the data
    if ( !mesh.checkConnection() )
    {
      Serial.println("Renewing Address");
      mesh.renewAddress();

    }
  }
  else
  {
    Serial.println("node status msg Sent");
    return;
  }

}
Run Code Online (Sandbox Code Playgroud)

Gar*_*rey 6

您的 C 程序只是发送结构,但该结构不包含任何字符串数据。它只包括不能被任何其他进程(不同地址空间)使用的指针(地址)。

您需要确定一种发送所有必需数据的方法,这可能意味着发送每个字符串的长度及其数据。

一种方法是使用最大长度并将字符串存储在结构中:

struct node_status
{
  char node_type[48];
  char sub_type[48];          // set the type of incubator
  int sub_type_id;
  bool sleep = false;         // set to sleep
  int check_in_time = 1000;   // set check in time
  bool LOCK = false;      // set if admin control is true/false
} nodeStatus;
Run Code Online (Sandbox Code Playgroud)

然后您需要将字符串复制到这些缓冲区中而不是分配它们,并检查缓冲区溢出。如果用户曾经输入过这些字符串,就会有安全隐患。

另一种方法是在发送数据时将数据打包到一个块中。您也可以使用多次写入,但我不知道这个网格库或您将如何设置type参数来做到这一点。使用缓冲区类似于:

// be sure to check for null on your strings, too.
int lennodetype = strlen(nodeStatus.node_type);
int lensubtype = strlen(nodeStatus.sub_type);
int bufsize = sizeof(nodeStatus) + lennodetype + lensubtype;
byte* buffer = new byte[bufsize];

int offset = 0;
memcpy(buffer+offset, &lennodetype, sizeof(int));
offset += sizeof(int);
memcpy(buffer+offset, nodeStatus.node_type, lennodetype * sizeof(char));
offset += lennodetype * sizeof(char);
memcpy(buffer+offset, &lensubtype, sizeof(int));
offset += sizeof(int);
memcpy(buffer+offset, nodeStatus.sub_type, lensubtype * sizeof(char));
offset += lensubtype * sizeof(char);
// this still copies the pointers, which aren't needed, but simplifies the code
// and 8 unused bytes shouldn't matter too much. You could adjust this line to 
// eliminate it if you wanted.
memcpy(buffer+offset, &nodeStatus, sizeof(nodeStatus));

if (!mesh.write(buffer, 
/*type*/ 126, 
bufsize, 
/*to node*/ 000))
  { // Send the data
    if ( !mesh.checkConnection() )
    {
      Serial.println("Renewing Address");
      mesh.renewAddress();

    }
  }
  else
  {
    Serial.println("node status msg Sent");
  }
delete [] buffer;
Run Code Online (Sandbox Code Playgroud)

既然数据实际上已发送(读取数据的先决条件),您需要的数据应该都在payload数组中。您需要解压它,但不能只传递解压单个字节,它需要数组:

len = struct.unpack("@4i", payload)
offset = 4
node_type = struct.unpack_from("{}s".format(len), payload, offset)
offset += len
len = struct.unpack_from("@4i", payload, offset)
offset += 4
sub_type = struct.unpack_from("{}s".format(len), payload, offset)
offset += len
...
Run Code Online (Sandbox Code Playgroud)