我有一个包结构,它包含一些头信息和一个malloc'ed字节数组。当我想要写那个包时,我malloc一个新的字节数组,插入头信息,然后memcpy structs有效负载字节数组到新的缓冲区中。我能在不创建副本的情况下创建字节数组吗?这将在一个有2K内存的Arduino上运行我想让每个字节都算数。我还在考虑保留原始字节数组的完整性,只是使指针指向与字段相关的字节数组中的值。
下面是我当前的代码:
// .h
typedef struct BLEPacket {
uint8_t protocol;
uint8_t meta;
uint16_t length;
uint16_t checksum;
const uint8_t* payload;
} BLEPacket;
//.c
uint8_t* bytesFromBLEPacket(BLEPacket packet){
uint8_t *outBuffer = malloc(packet.length);
outBuffer[0] = packet.protocol;
outBuffer[1] = packet.meta;
outBuffer[2] = highOrderByte(packet.length);
outBuffer[3] = lowOrderByte(packet.length);
outBuffer[4] = highOrderByte(packet.checksum);
outBuffer[5] = lowOrderByte(packet.checksum);
if (packet.payload != NULL){
memcpy(outBuffer+PACKET_HEADER_SIZE, packet.payload, packet.length - PACKET_HEADER_SIZE);
}
return outBuffer;
}
编辑:我没有很好的C背景,所以我不完全确定是否/如何以这种方式直接访问内存。我能做像byte[0] = packet.payload - PACKET_HEADER_SIZE
这样的吗?
// ios client.m
-(void)sendMessage:(NSString*)message {
NSData *data = [message dataUsingEncoding:NSASCIIStringEncoding];
BLEPacket packet = BLEPacketCompose(MetaMessage, data.bytes, data.length);
[self writePacket:packet];
}
-(void)writePacket:(BLEPacket)packet {
uint8_t bytes[packet.length];
bytesFromBLEPacket(packet,bytes); // updated with non-malloc version
NSData *data = [NSData dataWithBytes:bytes length:packet.length];
[self write:data]; // CoreBluetooth update characteristic value
}
// arduino.ino - a simple echo for now. I'm planning on including the same BLEPacket.h/.c file
void setup() {
Serial.begin(115200);
}
void loop() {
if(Serial.available()) {
Serial.write(Serial.read()); //echo, writes one byte at a time, in order
}
}
我还需要将数据包作为字节数组进行校验和。它也发生在我现在,我可以硬编码校验和/字节逐字节写入数据包头,而不是迭代负载。但是,为了学习,我如何才能访问结构体的字段作为字节数组而不将它们转储到另一个数组中?
首先,不要在小型rtos和裸机嵌入式系统上使用C中的malloc/free和c++中的new/delete。大禁忌!
其次,是的,您可以传入一个指针,该指针指向函数外部静态定义的缓冲区。它看起来像这样:
uint8_t bytesFromBLEPacket(BLEPacket packet, uint8_t* outBuffer, uint16_t outBufferSize) {
// Do some basic sanity checking on the buffer size that was passed in
if ( outBufferSize < 6 ) {
// buffer is too small, return some error
return 1;
}
if ( outBuffer == NULL ) {
// buffer not allocated, return some error
return 2;
}
outBuffer[0] = packet.protocol;
outBuffer[1] = packet.meta;
outBuffer[2] = highOrderByte(packet.length);
outBuffer[3] = lowOrderByte(packet.length);
outBuffer[4] = highOrderByte(packet.checksum);
outBuffer[5] = lowOrderByte(packet.checksum);
if (packet.payload != NULL){
memcpy(outBuffer+PACKET_HEADER_SIZE, packet.payload, packet.length - PACKET_HEADER_SIZE);
}
return 0;
}
// You can call your new function like so:
#define BUFF_SIZE 10
uint8_t buffer[BUFF_SIZE] = {0};
uint16_t bufferSize = BUFF_SIZE;
int status = bytesFromBLEPacket( packet, buffer, bufferSize );