c - 指向现有数组而不是副本的指针

标签 c arrays pointers

我有一个 Packet 结构,它包含一些 header 信息和一个 malloc'ed 字节数组。当我想写出那个数据包时,我 malloc 一个新的字节数组,插入 header 信息,然后将结构有效负载字节数组 memcpy 到新的缓冲区中。我可以在不创建副本的情况下制作字节数组吗?这将在具有 2K RAM 的 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
    }
}

我还需要将数据包作为字节数组来对其进行校验和。现在我也想到,我可以在校验和/逐字节写入数据包 header 时硬编码,而不是迭代有效负载。但是,为了学习,我如何才能将结构的字段作为字节数组访问而不将它们转储到另一个数组中?

最佳答案

首先,不要在小型 RTOS 和裸机嵌入式系统上使用 C 中的 malloc/free 和 C++ 中的 new/delete。 Big no-no!

其次,是的,您可以传入一个指向在函数外部静态定义的缓冲区的指针。它看起来像这样:

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 );

关于c - 指向现有数组而不是副本的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30654029/

相关文章:

sql - 排除匹配的数组元素

c++ - 通过指针初始化的字段有问题

c - 在 C 中实现 shell 时出错

android - 将 C 代码文件合并为一个 C 代码文件

适用于 Windows 7 的 C 编译器/IDE?

C 结构实例覆盖先前的实例

c - 制作一个函数来更新二维数组井字游戏表的 Action

c - 段错误(核心转储)- 简单

c++ - 将未使用的值初始化为 0 c++ 数组

python - 如何在不使用 numpy 的情况下将 2D 列表展平为 1D?