簡體   English   中英

無回調的Nanopb

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM