标签:
先存下,省的麻烦:
Rather than reproduce all the documentation of the main Google Protocol Buffers project page, I‘ll just reference it - so please read at least the language guide before going any further. The rest of the wiki assumes you already know the basics of Protocol Buffers. Likewise, currently the project only works on Windows and .NET; when support is provided for Mono on other platforms, the documentation will be updated.
First, either grab the source or a distribution. All new development is now done in Mercurial on Google Code; the previous github repository is obsolete.
If you fetched the source version, build the code. From the build directory, run (for a Release build):
This will create a directory build_output\Package containing:
In-keeping with the sample provided in the main project, the C# port comes with an address book application so you can see the basics of how to get going with Protocol Buffers. The code is built as part of the normal build in the source distribution, but we‘ll take it step by step here.
Let‘s start off with the addressbook.proto file which describes the messages. This lives in protos/tutorial in the source distribution.
package tutorial; import "google/protobuf/csharp_options.proto"; option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.Examples.AddressBook"; option (google.protobuf.csharp_file_options).umbrella_classname = "AddressBookProtos"; option optimize_for = SPEED; message Person { required string name = 1; required int32 id = 2; // Unique ID number for this person. optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; } // Our address book file is just one of these. message AddressBook { repeated Person person = 1; }
This is mostly just the same as the file in the main Protocol Buffers project, but there are a few tweaks:
Other options are available - see DescriptorOptions for details.
For simplicity, I would recommend copying protoc.exe from the Protoc directory into the Release directory; ProtoGen.exe can spot the existence of protoc.exe in the current directory (or in the path) and run it automatically. This is simpler than the old "two step" approach.
protogen ..\protos\tutorial\addressbook.proto
..\protos\google\protobuf\csharp_options.proto
..\protos\google\protobuf\descriptor.proto
--proto_path=..\protos
That will create a collection of .cs files in the current directory. We only actually need AddressBookProtos.cs - the others are the dependencies (the core Protocol Buffers descriptors and the C# options). You can optionally ignore dependencies, and also specify the output directory as of version 2.3.
We‘ll look into ways of making this slightly simpler... in particular, protogen now allows you to specify C# options on the command line, rather than in the proto file.
A few words of advice
tutorial/addressbook.proto:1:1: Expected top-level statement (e.g. "message").
The best way to fix this is with Visual Studio. Open the proto file and select "File" -> "Save as...". From the save dialog click the down arrow next to the save button and select "Save with Encoding". Select the "US-ASCII" codepage (near the bottom) and click save.
2. It‘s often easiest keep all your proto files in a single directory tree. This allows to omit the --proto_path option by running protoc.exe from the top of the this directory tree. Always keep the ‘google/protobuf/*.proto‘ files available so that you can import them to specify options, or use the options through protogen.
3.Unlike a programming language like C# it is usually expected that your proto file will specify numerous messages, not one. Name your proto files based on the namespace, not the message. Create proto files only as often as you would create a new namespace to organize those classes.
The following example uses the classes generated by the above proto file to perform these operations:
static void Sample() { byte[] bytes; //Create a builder to start building a message Person.Builder newContact = Person.CreateBuilder(); //Set the primitive properties newContact.SetId(1) .SetName("Foo") .SetEmail("foo@bar"); //Now add an item to a list (repeating) field newContact.AddPhone( //Create the child message inline Person.Types.PhoneNumber.CreateBuilder().SetNumber("555-1212").Build() ); //Now build the final message: Person person = newContact.Build(); //The builder is no longer valid (at least not now, scheduled for 2.4): newContact = null; using(MemoryStream stream = new MemoryStream()) { //Save the person to a stream person.WriteTo(stream); bytes = stream.ToArray(); } //Create another builder, merge the byte[], and build the message: Person copy = Person.CreateBuilder().MergeFrom(bytes).Build(); //A more streamlined approach might look like this: bytes = AddressBook.CreateBuilder().AddPerson(copy).Build().ToByteArray(); //And read the address book back again AddressBook restored = AddressBook.CreateBuilder().MergeFrom(bytes).Build(); //The message performs a deep-comparison on equality: if(restored.PersonCount != 1 || !person.Equals(restored.PersonList[0])) throw new ApplicationException("There is a bad person in here!"); }
标签:
原文地址:http://www.cnblogs.com/designyourdream/p/4267230.html