protobuf-lua-gen 中使用 bytes
protobuf - lua -gen 中的数据类型参考下图
bytes 我们就用string 来传值就可以。
比如下面的 Person.proto
message Person { required int32 id = 1; required bytes param = 2; }
可以下如下使用
package.path = package.path .. ';../protobuf/?.lua;../protobuf/luascript/?.lua' package.cpath = package.cpath .. ';../protobuf/?.so' require 'Person_pb' local person= Person_pb.Person() person.id = 1000 person.param=tostring(123) local data = person:SerializeToString() print(person)
更多请查看 https://github.com/indygreg/lua-protobuf/wiki/Lua-API
Lua API
This page documents the API by which protocol buffers are used in Lua.
Protocol Buffer Support
The following table describes the level of support for protocol buffer message features:
Definitions | Support Level |
---|---|
Optional Fields | Full |
Required Fields | Full |
Repeated Fields | Full |
Default Values | Full |
Enumerations | Full |
Nested Types | Full |
Groups | Won't Implement (deprecated) |
Extensions | Planned |
Nested Extensions | TBD |
Services | Planned |
Options | Planned |
The following table describes support for the scalar field types on messages:
Type | Supported? | Lua Type |
---|---|---|
double | Yes | number |
float | Yes | number |
int32 | Yes | number |
int64 | Not Robust | number |
uint32 | Yes | number |
uint64 | Not Robust | number |
sint32 | Yes | number |
sint64 | Not Robust | number |
fixed32 | Yes | number |
fixed64 | Not Robust | number |
sfixed32 | Yes | number |
sfixed64 | Not Robust | number |
bool | Yes | boolean |
string | Yes | string |
bytes | Yes | string |
Each protocol buffer message is registered as a Lua type. The type name is
"protobuf." + :package + "." + :message_name
For example, the messages in the following protocol buffer definition:
package acme.example;
message msgA {
optional string name = 1;
}
message lua {
repeated uint32 value = 1;
}
correspond to the Lua types:
protobuf.acme.example.msgA
protobuf.acme.example.lua
From Lua, you can create protocol buffer messages by calling the new function of the Lua message type:
-- create an empty msgA message from the acme.example package
msg = protobuf.acme.example.msgA.new()
This is equivalent to calling the C++ constructor with no arguments.
If you have a string containing the serialized content of a message, call the parsefromstring function of the Lua message type:
-- parse message from contents of a variable, serialized
msg = protobuf.acme.example.msgA.parsefromstring(serialized)
Each Lua message type has a handful of common functions:
-- message in variable 'msg'
-- obtain serialized value of message, as a string
serialized = msg:serialized()
-- clear all fields from message
msg:clear()
Each message field defines a number of accessor and mutator methods.
The name of these functions is the form:
:action + "_" + :field
All field labels (required, optional, repeated) have the clear, get, and set actions:
msg:clear_name()
value = msg:get_name()
msg:set_name("new value")
For repeated fields, get and set add a required argument, which is the offset to get/set. By Lua convention, the first element is offset 1.
value1, value2 = msg:get_name(1), msg:get_name(2)
msg:set_name(1, "new value")
-- this will result in error b/c the offset is invalid
value = msg:get_name(0)
-- you will also get an error if you attempt to retrieve an offset that doesn't exist
-- assume msg:size_name() == 2
-- this will error:
msg:get_name(3)
This function does not return any values.
required and optional fields have the has action:
bool = msg:has_name()
repeated fields have the size action, which returns the number of elements:
size = msg:size_multiple()
Embedded Messages
It is possible to embed one protocol buffer message inside another. This is supported in the Lua interface, but the API is slightly different from scalar values.
First, we mimic the C++ API where the )set_()_ function doesn't exist.
-- this clears a message
msg:set_embedded(nil)
-- this throws an error
msg:set_embedded(msg_instance)
To modify embedded messages, you call the get()_ function and modify the returned object.
embedded = msg:get_embedded()
embedded:set_field(new_value)
-- change reflected in parent message automatically
To add an embedded message to a repeated field:
embedded = msg:add_embedded()
-- do stuff with message
Currently there is a bug dealing with treatment of the mutable pointers Lua is using under the hood. The following will likely crash your process:
embedded = msg:get_embedded()
msg:clear_embedded()
-- crash happens on next line
embedded:get_value()
This will hopefully be fixed in a later version.
Messages can also be treated as tables. Just set the message field name as the table key.
value = msg['name']
msg['name'] = 'new value'
Repeated message fields are themselves tables. However, they are indexed by an integer value, starting from 1, as that is the Lua convention.
value = msg['value'][1]
Table access is not yet available. The syntax is documented here for reference during implementation.
Enumerations are represented as Lua tables. Table keys are the strings which correspond to the enumerated values. Table values are the respective integer values of these keys.
Enumeration type names are assigned from the package, message, and enumeration name.
If the enumeration was defined at file/package scope (outside a message), the Lua type name will be:
:package + "." + :enum
If the enumeration was defined inside a message, the Lua type name will be:
:package + "." + :message + "." + :enum
Let's take the following .proto file as an example:
package acme;
enum Color {
RED = 0;
GREEN = 1;
BLUE = 2;
}
message Car {
optional Color color = 1;
}
message Sign {
enum Shape {
SQUARE = 1;
ROUND = 2;
}
optional Shape shape = 1;
}
Here is how you would interact with the enumerations:
car = protobuf.acme.Car.new()
car.set_color(protobuf.acme.Color['GREEN'])
color = car.get_color()
sign = protobuf.acme.Sign.new()
sign.set_shape(protobuf.acme.Sign.Shape['SQUARE'])
Of course, the "." syntax in Lua is just a shortcut for table access, so if you really wanted:
value = protobuf['acme']['Color']['GREEN']