![](/img/trans.png)
[英]creating callbacks and structs for repeated field in a protobuf message in nanopb in c
[英]Nanopb without callbacks
我正在使用Nanopb嘗試從基於VxWorks的National Compact Compact RIO(9025)發送protobuf消息。 我的交叉編譯效果很好,甚至可以發送不需要額外編碼的數據類型的完整消息。 讓我着迷的是回調。 我的代碼是通過LabVIEW交叉編譯和調用的,基於Nanopb的基於回調的結構似乎在目標計算機上中斷(錯誤,崩潰,目標重新啟動等)。 如果我在沒有任何回調的情況下運行它,則效果很好。
這是有問題的代碼:
bool encode_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
{
char *str = "Woo hoo!";
if (!pb_encode_tag_for_field(stream, field))
return false;
return pb_encode_string(stream, (uint8_t*)str, strlen(str));
}
extern "C" uint16_t getPacket(uint8_t* packet)
{
uint8_t buffer[256];
uint16_t packetSize;
ExampleMsg msg = {};
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
msg.name.funcs.encode = &encode_string;
msg.value = 17;
msg.number = 18;
pb_encode(&stream, ExampleMsg_fields, &msg);
packetSize = stream.bytes_written;
memcpy(packet, buffer, 256);
return packetSize;
}
這是原始文件:
syntax = "proto2"
message ExampleMsg {
required int32 value = 1;
required int32 number = 2;
required string name = 3;
}
我也嘗試將回調設置為外部“ C”,並且它什么都沒有改變。 我也嘗試添加最大長度的nanopb選項文件,或者它無法正確理解它,或者它也不起作用。
如果我從原始消息中刪除字符串並刪除回調,則效果很好。 在該LabVIEW-> C庫環境中,回調結構似乎無法正常工作。 沒有回調結構,還有其他方法可以編碼消息嗎? 還是以某種方式將回調嵌入到getPacket()函數中?
更新的代碼:
extern "C" uint16_t getPacket(uint8_t* packet)
{
uint8_t buffer[256];
for (unsigned int i = 0; i < 256; ++i)
buffer[i] = 0;
uint16_t packetSize;
ExampleMsg msg = {};
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
msg.name.funcs.encode = &encode_string;
msg.value = 17;
msg.number = 18;
char name[] = "Woo hoo!";
strncpy(msg.name, name, strlen(name));
pb_encode(&stream, ExampleMsg_fields, &msg);
packetSize = stream.bytes_written;
memcpy(packet, buffer, sizeof(buffer));
return packetSize;
}
更新的原始文件:
syntax = "proto2"
import "nanopb.proto";
message ExampleMsg {
required int32 value = 1;
required int32 number = 2;
required string name = 3 [(nanopb).max_size = 40];
}
您可以通過使用.proto文件中的(nanopb).max_size = 123
選項為字符串字段提供最大大小來避免回調。 然后nanopb可以在結構中生成一個簡單的char
數組( 文檔的相關部分 )。
關於為什么回調不起作用:只是一個猜測,但是請嘗試在回調函數中也添加extern "C"
。 我假設您在那里使用C ++,所以也許在該平台上,C和C ++調用約定不同,這會導致崩潰。
VxWorks串行控制台是否提供有關崩潰的更多信息? 我不記得是否對從LabView調用的函數執行此操作,因此直接從VxWorks shell運行一些測試代碼也值得嘗試。
也許第一個障礙是代碼如何處理字符串。
LabVIEW的本機字符串表示形式不像C那樣以null終止,但是您可以配置LabVIEW以使用其他表示形式,或者更新代碼以處理LabVIEW的本機格式。
LabVIEW以特殊格式存儲字符串,其中字符數組的前四個字節形成一個32位帶符號整數,用於存儲字符串中出現的字符數。 因此,具有n個字符的字符串需要n + 4個字節存儲在內存中。
LabVIEW幫助:在調用庫函數節點中使用數組和字符串
http://zone.ni.com/reference/en-XX/help/371361L-01/lvexcodeconcepts/array_and_string_options/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.