该pb_callback_t
结构包含一个void* arg
字段,您可以使用该字段通过arg
参数将任何自定义数据传递给编码/解码函数。
在这种情况下,您可以这样做:
int main()
{
...
featurefile.features.Id.arg = "something";
featurefile.features.Id.funcs.encode = &encode_string;
}
请注意,arg
参数是指向 的指针,void * const
因此您将始终必须取消引用它:
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));
}
请注意,您可以将指针传递给任何结构,即您可以轻松地创建一种“解析上下文”结构并将其传递,这样您就不需要关心解析函数将如何使用它。
在这种情况下,它可能类似于:
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));
}