当字符串是 pb_callback_t 类型时如何对字符串进行编码 [英] How to encode a string when it is a pb_callback_t type

查看:116
本文介绍了当字符串是 pb_callback_t 类型时如何对字符串进行编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Nanopb,其中生成的 proto 文件中的字符串变量被转换为 pb_callback_t

I'm working with Nanopb, where the string variable from the generated proto file, is converted to pb_callback_t

到目前为止,我正在尝试使用 nanopb 回调的测试示例;

So, far I'm trying with a test example of callbacks from nanopb;

bool encode_string(pb_ostream_t* stream, const pb_field_t* field, void* const* arg)
{
    char str[14] = "Hello world!";

    if (!pb_encode_tag_for_field(stream, field))
        return false;

    return pb_encode_string(stream, (uint8_t*)str, strlen(str));
}

int main()
{
FeatureFile featurefile = FeatureFile_init_zero;
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));

featurefile.features.Id.funcs.encode = &encode_string;
}

但是在这个例子中,字符串Hello world!"是相当硬编码的 xD,我如何才能从 main 动态地将字符串传递给该函数?

But with this example, the string "Hello world!" is pretty hardcoded xD, how can I instead pass a string dynamicly to that function, from main?

推荐答案

pb_callback_t 结构包含一个 void* arg 字段,您可以使用该字段将任何自定义数据传递给通过 arg 参数实现编码/解码功能.

The pb_callback_t struct contains a void* arg field which you can use to pass any custom data to the encode/decode function through the arg parameter.

在这种情况下,您可以:

In this case you could do:

int main()
{
    ... 
    featurefile.features.Id.arg = "something";
    featurefile.features.Id.funcs.encode = &encode_string;
}

请注意,arg 参数是一个指针,指向 void * const,因此您必须始终取消引用它:

And note that the arg parameter is a pointer to void * const, so you will always have to dereference it:

bool encode_string(pb_ostream_t* stream, const pb_field_t* field, void* const* arg)
{
    const char* str = (const char*)(*arg);

    if (!pb_encode_tag_for_field(stream, field))
        return false;

    return pb_encode_string(stream, (uint8_t*)str, strlen(str));
}

请注意,您可以将指针传递给任何结构,即您可以轻松创建一种解析上下文"结构并将其传递,这样您就无需关心解析函数将如何使用它.

Note that you can pass a pointer to any struct, i.e. you can easily create a sort of a "parsing context" struct and pass it around so that you don't need to care how the parsing func will use it.

在这种情况下,它可能是这样的:

In this case, it could be something like:

typedef struct
{
    const char * something;
    const char * whatever;
    ...
}
callback_context_t;

int main()
{
    callback_context_t ctx = { .something = "something" };

    // this way you always pass the same pointer type
    featurefile.features.Id.arg = &ctx;
    featurefile.features.Id.funcs.encode = &encode_string;
}

bool encode_string(pb_ostream_t* stream, const pb_field_t* field, void* const* arg)
{
    // ...and you always cast to the same pointer type, reducing
    // the chance of mistakes
    callback_context_t * ctx = (callback_context_t *)(*arg);

    if (!pb_encode_tag_for_field(stream, field))
        return false;

    return pb_encode_string(stream, (uint8_t*)ctx->something, strlen(ctx->something));
}

这篇关于当字符串是 pb_callback_t 类型时如何对字符串进行编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆