8

google protobufs を使用して、ネットワーク上でデータを渡します。サーバー側はプラグインに似ているため、protobuf メッセージを処理するモジュールのいくつかは DLL です。一部の DLL は他の DLL に依存し、他の DLL のメッセージを使用して独自のメッセージを定義します。

したがって、A.DLL には、メッセージ クラスa.protoで生成されるものがあります。protoc コンパイラで文書化されていないオプションを使用すると、メッセージ クラスが DLL エクスポートとして宣言されます。a.pb.h/ccMsgAdllexport_decl

ここで、B.DLL は A.DLL に依存し、b.proto次のようになります。

import "a.proto";
message b 
{
    required int32 some_number = 1;
    required PackageA.MsgA some_a = 2;
}

最後に、パーツをまとめる実行可能ファイルもメッセージに依存しますMsgA。protobuf ライブラリも DLL としてビルドされ、すべてにリンクされています。それはすべてビルドして実行します。

しかし、光の勢力がDLL 配布の削減を要求しています! そこで、モジュール A (これは、他の多くのプラグイン DLL が使用するメッセージと小さなユーティリティの単なるコレクションです) を、DLL ではなくスタティック ライブラリとして構築しました。B.DLL と実行可能ファイルの両方が A にリンクしており、これまでのところすべて問題ありません。

A は静的にリンクMsgAされているため、すべての DLL と EXE で完全に定義されます。生成された C++ コードの静的データはすべて const であるため、これで問題ありません。では、最終プロセスで複数のコピーが存在する場合はどうなるでしょうか。すべてのコピーは同一です。

しかし、新しく構築したプロセスを実行すると、libproto は実際に役立つ例外をスローします。MsgA のファイル ID は記述子マップ(またはそのようなもの) に既に存在します。つまり、 の定義が複数あることがMsgA 大きな問題です。

最後に、ここに質問があります。

  • libproto を DLL として使用する代わりに静的にリンクした場合、エラーは解消されますか?
  • MsgA複数の の定義がDLL 全体に散らばっていても本当に安全ですか?

最初のポイントは、protobuf ライブラリの再構築に取りかかれば、おそらく数日で答えられると思いますが、2 番目のポイントは、私の現在の知識を少し超えています。また、proto libs を再コンパイルする手間を省くことができる、迅速なアップまたはダウンの回答を得たいと考えています。

4

1 に答える 1

1

ネットワーク全体で RPC にプロトバッファを使用しました (Google もこれを行っています - ドキュメント ページを参照してください)。proto バッファーを使用するすべての人に同様の定義がある限り、1 つの定義が他の定義によってシリアル化されたデータを問題なく逆シリアル化します。実際、タグ番号を再割り当てしない限り、古いバージョンのプロトコル バッファ定義は新しいバージョンと問題なくやり取りできます (デシリアライズ定義の「必須」フィールドがストリームに存在する限り、それは成功した)。

それが役立つことを願っています。

于 2011-04-23T17:19:32.847 に答える