aardio官方社区

标题: 请教protobuf的bytes类型使用 [打印本页]

作者: wudijushi    时间: 2012-7-19 15:58
标题: [i=s] 本帖最后由 wudijushi 于 2012-7-23 11:05 编辑 [/i] 定义的message如下:[code]message Msg{
本帖最后由 wudijushi 于 2012-7-23 11:05 编辑

定义的message如下:
  1. message Msg{
  2. required int32 cmd = 1;
  3. optional bool compress = 2;

  4. message Sub{
  5. optional int32 cmd = 1;
  6. optional bytes msg = 2;
  7. }
  8. optional Sub context = 3;
  9. }
复制代码
bytesMay contain any arbitrary sequence of bytes.stringByteString
protobuf language guide 是这么描述bytes类型的,我理解它是个字节数组(不是是否有错?)


我的目的是使用 msg 字段存储编译过的aardio代码
  1. var bytes = {byte msg[] = dumpcode( assert( loadcode("test.aardio")))};
  2. var send = Msg();
  3. send.context = Msg.Sub();
  4. send.cmd = 1;
  5. send.context.msg = bytes.msg;
  6. send.serializeToString();
复制代码
其实我也尝试过直接传递  string.load("test.aardio")  或者 dumpcode( assert( loadcode("test.aardio"))) 到send.context.msg,但都会报错!
估计是我使用 bytes 类型不当,message库报的错也不理解,所以不知怎样修正,请求大家指导,谢谢!

-------------------------------------------------------------------------------------------------------------------------------------------------------
二次补充:
protobuf 生成的aardio库:
   
import protobuf.message;
import util.metaProperty;
class Msg {
   
ctor(reader){
        
this = ..protobuf.message(reader)
        
        
this.fields[1] = "..protobuf.type.int";
        
this.values[1] = null;
     
        
this.fields[2] = "..protobuf.type.bool";
        
this.values[2] = null;
     
        
this.fields[3] = "..Msg.Sub";
        
this.values[3] = null;
      
    }
    @_metaProperty ;
}

namespace Msg {
   
class Sub {
        
ctor(reader){
            
this = ..protobuf.message(reader)
            
               
this.fields[1] = "..protobuf.type.int";
            
this.values[1] = null;
         
            
this.fields[2] = "..protobuf.type.bytes";
            
this.values[2] = null;
           
        }
        @_metaProperty ;
    }
   
   
namespace Sub {
      
      
        _metaProperty  = ..util.metaProperty(
            _tostring =
function(){
               
return owner.serializeToString();
            };
            
            cmd = {
                _get =
function(){
                    
return owner._get_value(1);
                }
                _set =
function( value ){
                    
return owner._set_value(1, value);
                }   
            };
         
            msg = {
                _get =
function(){
                    
return owner._get_value(2);
                }
                _set =
function( value ){
                    
return owner._set_value(2, value);
                }   
            };
            
        )
    }
   
/**intellisense()
Msg.Sub = protobuf消息对象
Msg.Sub() = 创建protobuf消息对象
?Msg.Sub = !Msg_Sub.
!Msg_Sub.parseFromString(__/*字符串*/) = 二进制数据反序列化到消息对象
此函数自动清空所有数组值,但不会重置其他非数组字段值.
因此应对新创建的对象调用此函数.
!Msg_Sub.serializeToString() = 序列化消息对象,返回二进制字符串
!Msg_Sub.cmd = protobuf.type.int
!Msg_Sub.msg = protobuf.type.bytes
end intellisense**/
  
   
    _metaProperty  = ..util.metaProperty(
        _tostring =
function(){
            
return owner.serializeToString();
        };
        
    cmd = {
            _get =
function(){
               
return owner._get_value(1);
            }
            _set =
function( value ){
               
return owner._set_value(1, value);
            }   
        };
     
        compress = {
            _get =
function(){
               
return owner._get_value(2);
            }
            _set =
function( value ){
               
return owner._set_value(2, value);
            }   
        };
     
        context = {
            _get =
function(){
               
return owner._get_value(3);
            }
            _set =
function( value ){
               
return owner._set_value(3, value);
            }   
        };
        
    )
}

/**intellisense()
Msg = protobuf消息对象
Msg() = 创建protobuf消息对象
?Msg = !Msg.
!Msg.parseFromString(__/*字符串*/) = 二进制数据反序列化到消息对象
此函数自动清空所有数组值,但不会重置其他非数组字段值.
因此应对新创建的对象调用此函数.
!Msg.serializeToString() = 序列化消息对象,返回二进制字符串
!Msg.cmd = protobuf.type.int
!Msg.compress = protobuf.type.bool
!Msg.context = !Msg_Sub.
end intellisense**/


/*
message Msg{
    required int32 cmd = 1;
    optional bool compress = 2;
   
    message Sub{
        optional int32 cmd = 1;
        optional bytes msg = 2;
    }
    optional Sub context = 3;
}
*/


单独测试代码:
var code = /*
import win;
win.msgbox("hello")
*/

io.open()
import Msg;

var send = Msg();
send.context = Msg.Sub()

send.cmd =1 ;
send.context.msg =
dumpcode(assert(loadcode(code)))

var fun = loadcode(send.context.msg);
fun()

var bin = send.serializeToString()

io.print(
"size of send.context.msg",#send.context.msg)
io.print(
"size of bin:",#bin)

var recv = Msg();
recv.context = Msg.Sub();

recv.parseFromString(bin);  
// 出错了!! 'I dont understand this wired code:5'

io.print(
"size of recv.context.msg",#recv.context.msg)

作者: 不争    时间: 2012-7-19 17:00
标题: protobuf 中的 bytes就是aardio中的字符串, 所以不需要写的那么复杂,直接赋值就可以。 protobuf中的string类型也是aar
protobuf 中的 bytes就是aardio中的字符串,
所以不需要写的那么复杂,直接赋值就可以。

protobuf中的string类型也是aardio中的字符串,
区别是他会转换为UTF8编码,并且不能包含文本终结符'\0' (也就是C里的字符串指针)

另外测试你的代码并没有报错。


作者: wudijushi    时间: 2012-7-19 21:40
标题: [quote][color=#999999]不争 发表于 2012-7-19 17:00[/color] [color=#999999]protobuf 中的
不争 发表于 2012-7-19 17:00  protobuf 中的 bytes就是aardio中的字符串,  所以不需要写的那么复杂,直接赋值就可以。  

你好,<不争>,不好意思,搞错了,应该是在反序列时出错的…sorry
作者: 青菜头    时间: 2017-11-20 21:31
应该还不支持3.0以上吧。3.0有个默认不需要required,还多了一个map。不知道这个库能否支撑




欢迎光临 aardio官方社区 (http://bbs.aardio.com/) Powered by Discuz! X3.4