C# でシリアライズし、ZMQ を使用してネットワーク経由で送信したオブジェクトを C++ でデシリアライズする際に問題があります。C++ サーバー アプリケーション (Linux) が C# (Windows) からシリアル化されたメッセージを正常に受信し、メッセージを正常に逆シリアル化できる Windows に送り返すため、ZMQ 部分が正しく動作していると確信しています。その点で、あらゆる種類の切り捨てられたパケットまたはドロップされたパケットが発生しています。
ただし、Linux サーバーでメッセージを受信すると、C++ のデシリアライズ メソッドは正しくデシリアライズされず、一連のバイナリ データが 6 番目のフィールドにスローされます (これは MyObject.DebugString() で確認できます)。その他のフィールド。ただし、ここで奇妙なのは、5 つのフィールドを持つクラスが完全に正常に機能することです。C++ はそれを正しく逆シリアル化し、すべてのデータが正しく機能しています。以下は、私のコードのほんの一部です。どんな助けでも大歓迎です。
C#:
MemoryStream stream = new MemoryStream();
ProtoBuf.Serializer.Serialize<TestType>(stream, (TestType)data);
_publisher.Send(stream.ToArray());
C++:
message_t data;
int64_t recv_more;
size_t recv_more_sz = sizeof(recv_more);
TestType t;
bool isProcessing = true;
while(isProcessing)
{
pSubscriber->recv(&data, 0);
t.ParseFromArray((void*)(data.data()),sizeof(t));
cout<<"Debug: "<<t.DebugString()<<endl;
pSubscriber->getsockopt(ZMQ_RCVMORE, &recv_more, &recv_more_sz);
isProcessing = recv_more;
}
出力は次のようになります。
Debug: f: "4\000\000\000\000\000\"
コピーと貼り付けに問題がありますが、出力はおそらく 3 ~ 4 行分続きます。
これは私の TestType クラス (プロト ファイル) です。
package Base_Types;
enum Enumr {
Dog = 0;
Cat = 1;
Fish = 2;
}
message TestType {
required double a = 1;
required Enumr b = 2;
required string c = 3;
required string d = 4;
required double e = 5;
required bytes f = 6;
required string g = 7;
required string h = 8;
required string i = 9;
required string j = 10;
}
フィールド「f」がバイトとしてリストされているのは、UTF-8 エンコーディングに関する警告が表示される前に文字列だった場合、このクラスが 5 つのフィールド (列挙型はそれらの 1 つ) のみで動作する場合、それは与えられなかったからです。私にそのエラー。これは、逆シリアル化する代わりに、クラス全体のバイナリをフィールド "f" (フィールド 6) に投入するようなものです。
解決策: メモリがスレッド ソケットに送信される前にコピーされないという問題が発生しました。パブリッシャーが返送したとき、データをパッケージ化し、ルーターが受信したものを変更していました。内部で使用するデータを送信するには、C++ 側に memcpy() が必要です。助けてくれてありがとう。