简体   繁体   English

python struct 从 Berkeley DB 解压一个特定的 C 结构

[英]python struct unpack a specific C struct from Berkeley DB

I have the following C struct:我有以下 C 结构:

#define UUID4_LEN 37
...
typedef struct can_record {
    char id[UUID4_LEN];
    char *can_data;
} CAN_RECORD;

I am saving that record in Berkeley DB via the below function:我通过以下函数将该记录保存在 Berkeley DB 中:

int insert_record(DB **dbpp, CAN_RECORD * record) {
    DB *db;
    DBT key, data;
    int ret;

    db = *dbpp;

    memset(&key, 0, sizeof(DBT));
    memset(&data, 0, sizeof(DBT));

    uuid4_generate(record->id);

    key.data = record->id;
    key.size = (u_int32_t)strlen(record->id) + 1;

    data.data = &record;
    data.size = sizeof(CAN_RECORD);

    ret = db->put(db, 0, &key, &data, 0);

    if(ret != 0) {
        fprintf(stderr, "Unable to insert record %s, err: %s\n", record->id,
            db_strerror(ret));

        return ret;
    }

    printf("Record inserted %s %s\n", record->id, record->can_data);

    return ret;
    
}

NOTE: the record->data has already been pre-populated previously, and it is of a variable length, but it is a stringified JSON structure, ie:注意: record->data之前已经预先填充,它是可变长度的,但它是一个字符串化的 JSON 结构,即:

asprintf(&record.can_data, "{\"t\": \"%s\", \"b\": \"%s\", \"e\": \"%u\"\"}", U_UID, name, (unsigned)time(NULL));

I have a python process that reads the Berkeley DB (here is a small excerpt):我有一个读取 Berkeley DB 的 python 进程(这里是一小段摘录):

from berkeleydb import db
...
...
    cursor = self._db.cursor()
    record = cursor.first()
    while record:
        (id, data) = record
        self.log(f'RECORD: {id} {data}')

        id = struct.unpack("", id)
        data = struct.unpack("", data)

        self.log(f'DECODED: {id} {data}')

        record = cursor.next()
...

The record data looks like this:记录数据如下所示:

b'46c54a16-366a-4397-aa68-357ab5538590\x00'

and

b'P\x99\x12\x00x\xbb\xfd~(\xbb\xfd~\x16\x00\x00\x00\x04\x00\x00\x00x\xbb\xfd~\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x9f\x02A\x00\x00\x00\x00\x83.\xf0v@\x03\x00\x00\x08\x00\x00\x00\xf0h\x9e\x9fpo;\xcc\x1d\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00can0\x00\x00\x00\x00x\xbb\xfd~\x00\x00\x00\x00\x03\x00\x00\x00\xb0\xfa\x00A\x00\x00\x00\x00\x00\x00'

I am unable to figure out how I can use python's struct.unpack to decode the bytes string.我无法弄清楚如何使用 python 的struct.unpack来解码字节字符串。 I have tried variety of different formats, but have been unsuccessful.我尝试了各种不同的格式,但都没有成功。

How would you go about unpacking the struct, such that I have the original form.您将如何解压缩结构,以便我拥有原始形式。

Unfortunately, the Berkeley DB reader has to be in python.不幸的是,Berkeley DB 阅读器必须在 python 中。

Also note:另请注意:

data.data = &record;
data.size = sizeof(CAN_RECORD);

the data is the entire struct, which includes the id[UUID4_LEN] , and the *can_data .数据是整个结构,其中包括id[UUID4_LEN]*can_data

What would I need to do here:我需要在这里做什么:

    (id, data) = record
    id = struct.unpack("", id)
    data = struct.unpack("", data)

to achieve original form?实现原始形式?

Ok, for the time being, I did a workaround.好的,暂时,我做了一个解决方法。 Rather than:而不是:

data.data = &record;
data.size = sizeof(CAN_RECORD);

I did:我做了:

data.data = record->can_data;
data.size = (u_int32_t)strlen(record->can_data) + 1;

So, I only saved the string, rather than the entire struct.所以,我只保存了字符串,而不是整个结构。 Then, in my python, I simply did:然后,在我的 python 中,我只是做了:

(id, data) = record        
id = str(id, 'utf-8')
data = str(data, 'utf-8')
                
self.log(f'ID: {id}') 
self.log(f'DATA: {data}')

and that decoded the byte string, to just a string perfectly:并将字节字符串解码为完美的字符串:

ID: dacaf94f-ecf5-4252-89d8-e2c9deff8f8d
DATA: {"t": "", "b": "abc123", "e": "1653636766"}

Although, this has helped me progress without using python struct.unpack , I am still keen on understanding how to unpack structs in python, as I will likely have a future requirement with slightly more complicated struct definitions.虽然,这在不使用 python struct.unpack的情况下帮助我取得了进步,但我仍然热衷于了解如何在 python 中解压结构,因为我将来可能会有稍微复杂的结构定义的需求。

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

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