·ProtoBuf の概要
ProtoBuf は、単純にXML や JSON と比較できる構造化データのシリアル化メソッドであり、次の特徴があります。
- 言語、プラットフォームに依存しません。つまり、ProtoBuf は Java、C++、Python などの言語をサポートし、複数のプラットフォームをサポートします。
- 効率的です。つまり、XML よりも小さく (3 ~ 10 倍)、高速 (20 ~ 100 倍)、簡単です。
- 優れた拡張性と互換性。元の古いプログラムに影響を与えたり破壊したりすることなく、データ構造を更新できます。
・ProtoBuf取得
ここで選択したバージョンは ProtoBuf 3.5.x です。
合計 2 つの手順が必要です
1.Google.Protobuf
GitHub から完全バージョンのPortalを入手し、バージョン 3.5.x を選択します
2つの方法から選択できます
(1) Unityでソースコードを利用する
Google.Protobuf フォルダーは Unity に直接配置されます
(2) UnityでGoogle.Protobuf.dllを使用する
vs を使用して開き、release を使用して Google.Protobuf プロジェクトをコンパイルします。この DLL をリリース ディレクトリに取得し、ライブラリに置きます。
2.プロトック
GitHub から Windows バージョンのポータルを取得し、バージョン 3.5.1 を選択します。
ビン内で必要な protoc.exe を見つけます
proto ファイルを作成した後、protoc コンパイラーを使用して .proto ファイルをターゲット言語にコンパイルします。
·.protoファイル
テストファイルの内容
// 指定版本
syntax = "proto3";
// C#中的namespace
package ProtoTest
option optimize_for = SPEED;
// java文件路径
option java_package = "com.montior.proto";
// java文件名称
option java_outer_classname = "MonitorData";
// 消息结果。
message MsgResult {
// 结果码。
int32 code = 1;
// 错误消息。
string err_msg = 2;
}
// 接收包
message TaskProtocol {
// 数据类型
int32 packType = 1;
// 具体数据
bytes content = 3;
}
// 包的类型
enum PackType {
LOGIN = 0;
CREATE_TASK = 2;
DELETE_TASK = 3;
}
message LoginPack{
string username = 1;
}
message LoginPack2{
string username = 1;
}
message CreateTaskPack{
string taskId = 1;
string taskName = 2;
}
-
message: クラスに似たメッセージ タイプ
-
package: パッケージ名、CSharp の名前空間、さまざまなメッセージ タイプの競合を防ぐために使用されます。
-
enum: 列挙、これを言う必要がありますか?
-
option: オプション、ここで使用するオプションの説明
java_package = "com.example.foo";//java ファイルパス
オプション java_outer_classname = "Ponycopter";//java ファイル名
オプション optimize_for = SPEED;//設定可能 SPEED です、CODE_SIZE、または LITE_RUNTIME。これらの値は、次のように C++ および Java コードの生成に影響します。注: 上記のオプションは、CSharp では必要ありません。ただ楽しむためです。
- データの種類
protobuf データ型
説明
C++
ブール
ブール型
ブール
ダブル
64ビット浮動小数点数
ダブル
浮く
32 は浮動小数点数です
浮く
int32
32ビット整数、
整数
uin32
符号なし 32 ビット整数
符号なし整数
int64
64ビット整数
__int64
uint64
64 は符号なし整数です
符号なし __int64
sint32
32 ビット整数、負の数の処理がより効率的
int32
歌う64
64 ビット整数は負の数をより効率的に処理します
__int64
固定32
32ビット符号なし整数
符号なし int32
固定64
64ビット符号なし整数
符号なし __int64
固定32
32 ビット整数、負の数をより効率的に処理できます
符号なし int32
固定64
64は整数です
符号なし __int64
弦
ASCII 文字のみを処理できます
std::文字列
バイト
中国語などのマルチバイト言語文字を処理する場合
std::文字列
- キーワード
指定されたフィールド 説明する 必要 必須フィールドであることを示します。送信者を基準とした相対値である必要があります。このフィールドの値は、メッセージを送信する前に設定する必要があります。受信者は、このフィールドの意味を認識できる必要があります。必須フィールドが設定されていない場合、または送信前に必須フィールドが認識できない場合は、コーデック例外がスローされ、メッセージは破棄されます。 オプション オプション 送信者は、メッセージを送信するときに、このフィールドの値を選択的に設定するかどうかを選択できます。受信側では、オプションのフィールドが認識できれば、それに応じて処理されますが、認識できなければ、そのフィールドは無視され、メッセージ内の他のフィールドは通常どおり処理されます。---オプション フィールドの特性により、多くのインターフェイスでは、追加されたフィールドをアップグレード バージョンのオプション フィールドとして一律に設定するため、古いバージョンではプログラムをアップグレードすることなく新しいソフトウェアと正常に通信できますが、新しいフィールドでは通信できません。すべてのノードが新しい機能を必要とするわけではないため、オンデマンドのアップグレードとスムーズな移行を実現できます。 繰り返された フィールドに 0 ~ N 個の要素を含めることができることを示します。その特性はオプションと同じですが、毎回複数の値を含めることができます。値の配列を渡すと見なすことができます。
· Unityでのレイアウト
UnityProject
-Asset
--Libraries
---Google.Protobuf // Protobuf ソース ファイル/dll ファイル
--Scripts/Editor/Proto2CSEditor // .proto ファイルを cs コードに配置
--Scripts/ProtoMessage // 変換された cs コードを配置
-Proto
--monitorData.proto // .proto ファイルを配置
-- protoc.exe / /
protoc.exe を使用して .proto ファイルを .cs に変換する方法
[MenuItem("Tools/Proto2CS")]
public static void AllProto2CS()
{
string rootDir = Environment.CurrentDirectory;
string protoDir = Path.Combine(rootDir, "Proto/");
string protoc;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
protoc = Path.Combine(protoDir, "protoc.exe");
}
else
{
protoc = Path.Combine(protoDir, "protoc");
}
string hotfixMessageCodePath = Path.Combine(rootDir, "Assets", "Scripts", "ProtoMessage/");
string argument2 = $"--csharp_out=\"{hotfixMessageCodePath}\" --proto_path=\"{protoDir}\" monitorData.proto";
Run(protoc, argument2, waitExit: true);
UnityEngine.Debug.Log("proto2cs succeed!");
AssetDatabase.Refresh();
}
public static Process Run(string exe, string arguments, string workingDirectory = ".", bool waitExit = false)
{
try
{
bool redirectStandardOutput = true;
bool redirectStandardError = true;
bool useShellExecute = false;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
redirectStandardOutput = false;
redirectStandardError = false;
useShellExecute = true;
}
if (waitExit)
{
redirectStandardOutput = true;
redirectStandardError = true;
useShellExecute = false;
}
ProcessStartInfo info = new ProcessStartInfo
{
FileName = exe,
Arguments = arguments,
CreateNoWindow = true,
UseShellExecute = useShellExecute,
WorkingDirectory = workingDirectory,
RedirectStandardOutput = redirectStandardOutput,
RedirectStandardError = redirectStandardError,
};
Process process = Process.Start(info);
if (waitExit)
{
process.WaitForExit();
if (process.ExitCode != 0)
{
throw new Exception($"{process.StandardOutput.ReadToEnd()} {process.StandardError.ReadToEnd()}");
}
}
return process;
}
catch (Exception e)
{
throw new Exception($"dir: {Path.GetFullPath(workingDirectory)}, command: {exe} {arguments}", e);
}
}
· シリアル化と逆シリアル化
・栗をあげる
MsgResult result = new MsgResult
{
Code = -999,
ErrMsg = "Error"
};
TaskProtocol msgResult = new TaskProtocol
{
PackType = 111,
Content = result.ToByteString()
};
byte[] s = packer.SerializeTo(msgResult);
Debug.Log("---------------------------------------------------");
TaskProtocol response = new TaskProtocol();
packer.DeserializeFrom(response, s);
MsgResult responseMsgResult = new MsgResult();
packer.DeserializeFrom(responseMsgResult, response.Content.ToByteArray());
Debug.Log(response.PackType);
Debug.Log(responseMsgResult.Code);
Debug.Log(responseMsgResult.ErrMsg);
・Protobuf-net.dllはUnityでも使用可能
<!--今のところなし-->
・結論
まだ ProtoBuf をうまく設定できず、シリアル化および逆シリアル化する方法がわからない場合は、!!!
それから、もう何回か見てください、ハハハ