简体   繁体   English

如何将python字节数组附加到C++

[英]How to translate python byte array append to C++

I am very very very new to ROS and embedded C++ programming.我对 ROS 和嵌入式 C++ 编程非常陌生。 I hate Python and I wish to convert a node written originally in Python to C++.我讨厌 Python,我希望将最初用 Python 编写的节点转换为 C++。 I won't get into detail on this conversion I am happy with OOP approach I took (put subscriber callback into a class, put publisher as class member), the main issue however is a piece of code in python that deals with byte arrays needed for communication with Arduino.我不会详细介绍这种转换我对我采用的 OOP 方法感到满意(将订阅者回调放入一个类中,将发布者作为类成员),但是主要问题是 Python 中处理所需字节数组的一段代码用于与 Arduino 通信。 I never worked with bytes and bits in C++, and it turned out that people use Python for its friendly Pyserial library, while the equivalent approach in C++ is very dark, specially on Linux OS.我从来没有在 C++ 中使用过字节和位,结果证明人们使用 Python 作为其友好的 Pyserial 库,而 C++ 中的等效方法非常黑暗,特别是在 Linux 操作系统上。

Python code is: Python代码是:

def function_callback(my_data):
global packet
my_array=my_data.data
print(my_array)
packet = bytearray()
for byte in my_array:
    packet.append(byte+48)
packet.append(0x0A)
packet.append(0x0D)

I understand that this takes my_data which is of ROS std_msgs/ByteMultiArray type, passes the actual data from that message to array my_array, now the elements in this array are being read as ASCI instead as bits, so for loop adds 48 to each element in order to get their decimal value.我知道这需要 my_data 是 ROS std_msgs/ByteMultiArray 类型,将来自该消息的实际数据传递到数组 my_array,现在该数组中的元素被读取为 ASCI 而不是位,因此 for 循环将 48 添加到每个元素以获得它们的十进制值。 The last two appends are some special bytes needed in Arduino.最后两个附加是 Arduino 中需要的一些特殊字节。

In C++ I have no idea how to this.在 C++ 中,我不知道如何做到这一点。 I found instructions here and created a class SerialComm that in essence mimics that code, the most important method in that class should be:我在这里找到了说明并创建了一个类 SerialComm 本质上模仿该代码,该类中最重要的方法应该是:

void SerialComm::write_port(unsigned char* msg)
{ 
  int i=write(serial_port, msg, sizeof(msg));
}

where I am unsure if argument should have unsigned char* data type, but it seems that write function in unistd.h supports this.我不确定参数是否应该具有 unsigned char* 数据类型,但似乎 unistd.h 中的 write 函数支持这一点。

Overall, how do I prepare the "packet" and send it to be written to the port?总的来说,我如何准备“数据包”并将其发送到端口?

To be more specific the data I need to write is of std_msgs/ByteMultiArray type in ROS, I checked it and the actual data is std::vector<signed char> type, I attempted this as a solution:更具体地说,我需要写入的数据是 ROS 中的 std_msgs/ByteMultiArray 类型,我检查了它,实际数据是 std::vector<signed char> 类型,我尝试将其作为解决方案:

unsigned char* make_byte_array(std::vector<signed char> array) const
{
    unsigned char retval[array.size()+2];
    int i=0;
    while (i<array.size())
    {
       retval[i]=array[i];
       i++;
    }
    retval[i+1]=0x0A;
    retval[i+2]=0x0D;
    return retval;
 }

This function is clearly nonsense, but it compiles, it naturally does not work because address of retval variable is being returned and nothing else, but I was mainly trying to somehow pass unsigned char* to that write function to write data to the port.这个函数显然是无稽之谈,但它编译了,它自然不起作用,因为正在返回 retval 变量的地址而没有别的,但我主要是试图以某种方式将 unsigned char* 传递给该 write 函数以将数据写入端口。 The main issue of course is how to convert std::vector array obtained from std_msgs/ByteMultiArray into whatever is needed to write to arduino port and essentially mimic the packet being sent in Python solution.当然,主要问题是如何将从 std_msgs/ByteMultiArray 获得的 std::vector 数组转换为写入 arduino 端口所需的任何内容,并基本上模仿 Python 解决方案中发送的数据包。 I think I struggle here mostly in understanding the chars data types as I never really worked with them, all I recall is that they are important because have unit bit memory size.我想我在这里主要是在理解字符数据类型方面挣扎,因为我从未真正使用过它们,我只记得它们很重要,因为它们具有单位位内存大小。

Most direct solution:最直接的解决办法:

std::vector<signed char> make_byte_array(std::vector<signed char> array) const
{
    array.push_back('\n');
    array.push_back('\r');
    return array;
}

What's happening: array is passed by value so it's automatically copied.发生了什么: array是按值传递的,因此它会被自动复制。 We take advantage of this copy to eliminate the need to manually copy inside the function.我们利用这个副本来消除在函数内部手动复制的需要。 Then we append the line feed and carriage return and return the resulting vector .然后我们附加换行符和回车符并返回结果vector

To get the array stored inside the vector either use vector 's data method要获取存储在向量中的数组,请使用vectordata方法

signed char * data = result_vector.data();

or in the pre-c++11 world, I've never seen this trick not work:或者在 c++11 之前的世界中,我从未见过这个技巧不起作用:

signed char * data = &result_vector[0];

So... what went wrong?所以……出了什么问题? Returning an array in C++ is hard.在 C++ 中返回数组很困难。 Unlike everything else in C++, an array defaults to pass by reference thanks to Array Decay .与 C++ 中的其他所有内容不同,由于Array Decay ,数组默认通过引用传递。 retval decays to a pointer, the pointer is returned, and retval goes out of scope and is destroyed, leaving you with a pointer to invalid memory. retval衰减为一个指针,返回该指针,并且retval超出范围并被销毁,留下一个指向无效内存的指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM