日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

protobuf 中的嵌套消息的使用 主要对set_allocated_和mutable_的使用

發(fā)布時間:2025/3/15 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 protobuf 中的嵌套消息的使用 主要对set_allocated_和mutable_的使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
protobuf的簡單的使用,不過還留下了一個問題,那就是之前主要介紹的都是對簡單數(shù)據(jù)的賦值,簡單數(shù)據(jù)直接采用set_xx()即可,但是如果不是簡單變量而是自定義的復合類型變量,就沒有簡單的set函數(shù)調(diào)用了,下面看一個簡單的例子。

在網(wǎng)絡(luò)游戲中,游戲玩家之間的同步是一個最基本的功能,而同步是通過對坐標的廣播進行的,因此我們假設(shè)一個簡單的模型,當一個玩家的位置發(fā)生變化時,將玩家的新位置發(fā)給地圖內(nèi)所有玩家,根據(jù)這個情況寫出以下proto文件。

[cpp]?view plain?copy
  • message?PlayerPos??
  • {?????
  • ????required??uint32??playerID?=?1;???
  • ????required??float???posX?=?2?;??????
  • ????required??float???posY?=?3?;??
  • };??
  • ??
  • file??vector.protomessage??vector3D??
  • {??
  • ????required?float?x?=?1;??
  • ????required?float?y?=?2;??
  • ????required?float?z?=?3;??
  • };??
  • 這樣就有一個問題,現(xiàn)在的游戲都是3D游戲,因此需要xyz來表示位置,還需要另一組xyz來表示朝向,如果用簡單變量的話就會顯的很亂,而且無論是位置還是朝向其實都是一組xyz,因此可以將xyz抽出來成為一個復合數(shù)據(jù)類型,單獨放在一個文件中。這樣就構(gòu)成以下文件。

    [cpp]?view plain?copy
  • file??Player.protoimport?"vector.proto";??
  • message?PlayerPos???
  • {??
  • ????required?uint32?playerID?=?1;??
  • ????required?vector3D??pos?=?2;??
  • };??
  • 編譯的時候先編譯vector文件,采用import時需要注意路徑,本例中兩文件在同一目錄下。

    [cpp]?view plain?copy
  • protoc?--cpp_out=.??vector.proto??Player.proto??
  • proto對應(yīng)的文件已經(jīng)生成了,但是該怎么賦值呢,查API查了半天有點不知所以,干脆來看生成的類文件的源代碼吧

    [cpp]?view plain?copy
  • //?required?uint32?playerID?=?1;????
  • inline?bool?has_playerid()?const;????
  • inline?void?clear_playerid();????
  • static?const?int?kPlayerIDFieldNumber?=?1;???
  • inline?::google::protobuf::uint32?playerid()?const;????
  • inline?void?set_playerid(::google::protobuf::uint32?value);????
  • //?required?.vector3D?pos?=?2;????
  • inline?bool?has_pos()?const;????
  • inline?void?clear_pos();????
  • static?const?int?kPosFieldNumber?=?2;????
  • inline?const?::vector3D&?pos()?const;????
  • inline?::vector3D*?mutable_pos();????
  • inline?::vector3D*?release_pos();????
  • inline?void?set_allocated_pos(::vector3D*?pos);??
  • 上面列出了生成的部分源代碼,主要是PlayerPos的操作變量的函數(shù),第一個playID很簡單,可以看到直接使用set_playerid ( ) 即可,但是對于嵌套的pos 發(fā)現(xiàn)沒有對應(yīng)的set_pos方法,不過發(fā)現(xiàn)了一個set_allocated_pos() 函數(shù),這個函數(shù)也是set開頭的,看看這個函數(shù)是干嘛的。

    [cpp]?view plain?copy
  • inline?void?PlayerPos::set_allocated_pos(::vector3D*?pos)???
  • {????
  • ????delete?pos_;????
  • ????pos_?=?pos;????
  • ????if?(pos)???
  • ????{??????
  • ????????set_has_pos();????
  • ????}???
  • ????else?{?????
  • ?????????clear_has_pos();????
  • ????}??
  • }??
  • 看上去可以賦值,直接調(diào)用set_allocated_pos() 進行賦值看一看
    [cpp]?view plain?copy
  • PlayerPos?player;??
  • vector3D??tmp;??
  • tmp.x?=?1;??
  • tmp.y?=?2;??
  • tmp.z?=?3;??
  • player.set_allocated_pos(&tmp)??
  • 編譯沒問題,但是運行時出現(xiàn)錯誤,而且是很奇怪的錯誤,仔細了查看一下PlayerPos的源碼,發(fā)現(xiàn)一個問題

    [cpp]?view plain?copy
  • ::vector3D*?pos_;??::google::protobuf::uint32?playerid_;??
  • 上面是PlayerPos中變量的保存形式,發(fā)現(xiàn)pos是作為一個指針存儲的,如果按照之前的賦值 tmp 是一個局部變量,函數(shù)返回時局部變量自動銷毀,而pos_保存的仍然是已被銷毀的tmp的位置,因此會出錯,如果采用new的話就可以解決這個問題,即賦值方法如下:

    [cpp]?view plain?copy
  • PlayerPos?player;vector3D??*tmp?=?new?Vector3D;??
  • tmp->x?=?1;??
  • tmp->y?=?2;??
  • tmp->z?=?3;??
  • player.set_allocated_pos(tmp)??
  • 這樣即可,編譯運行都沒有問題。?
    如此之外,還有一種賦值方法,就是調(diào)用mutable_pos()

    [cpp]?view plain?copy
  • inline?::vector3D*?PlayerPos::mutable_pos()???
  • {????
  • ????set_has_pos();????
  • ????if?(pos_?==?NULL)???
  • ????????pos_?=?new?::vector3D;????
  • ????return?pos_;??
  • }??
  • mutable_pos () 中自己new出了一個vector3D 對象,而vector3D中又實現(xiàn)了賦值的重載,因此可以這樣解決:

    [cpp]?view plain?copy
  • PlayerPos?player;??
  • vector3D??*tmp?=?player.mutable_pos();??
  • tmp->x?=?1;??
  • tmp->y?=?2;??
  • tmp->z?=?3;??
  • 總結(jié)

    以上是生活随笔為你收集整理的protobuf 中的嵌套消息的使用 主要对set_allocated_和mutable_的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。