4

シリアル化する [ProtoMember] 属性で装飾するフラグ付きの列挙型がありますそしてデシリアライズWin7 x64 を実行しているローカル ボックスでは問題ありません。

ただし、私のユース ケースには、Windows Server 2008 R2 Enterprise 64 ビットを実行しているサーバーでのシリアル化と、ローカル ボックスでの逆シリアル化が含まれます。逆シリアル化すると、「オーバーフロー例外が処理されませんでした。算術演算でオーバーフローが発生しました」という例外が発生します。ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(オブジェクト値、ProtoReaderソース)からスローされるようです。

enum を int に変更してシリアライズしてみましたサーバー上/ローカルでのデシリアライズが機能します。int の代わりに enum を使用したいと思います。私は何を間違っていますか?

これが適切な情報かどうかはわかりませんが、サーバーで実行する実行可能ファイルはローカル ボックスでビルドされています。

列挙は、参照された外部 dll からのものです。私のソリューションで列挙型コードを複製すると、逆シリアル化が機能します。例外がスローされるのは、外部 dll (ソース コードが不明であると思われる場所) から列挙型を使用していて、列挙型の値が 128 より大きい (と思われる) 場合のみです。私の場合、Status.Zeta と Status.すべてが例外をスローしました。適切に逆シリアル化された他の列挙値。列挙型は次のように定義されます。

[Flags]
public enum Status
{
    None = 0,
    Alpha = 1,
    Beta = 8,
    Gamma = 16,
    Delta = 32,
    Epsilon = 64,
    Zeta = 132,
    All = 255,
}

dll のコードを変更できません。どうすればこれを機能させることができますか?.proto ファイルは必要ですか? 可能であればこれを回避しようとしています。

4

2 に答える 2

3

これは、次の列挙型にのみ影響します。: byte

ああ!ブレインデッド エラーを見つけます。

case ProtoTypeCode.SByte: Emit(OpCodes.Conv_Ovf_U1); break;
case ProtoTypeCode.Byte: Emit(OpCodes.Conv_Ovf_I1); break;

これは、今日の後半に反転して展開されます。ありがとう。

正しく説明するbyteと、符号なし (0 から 255)、符号sbyte付き (-128 から 127) です。Conv_Ovf_U1基本的には、「に変換してオーバーフローをチェックする」( C#byteのキーワードがどのように機能するかなど) の IL であり、「に変換してオーバーフローをチェックする」です。したがって、値が 127 を超えるとオーバーフロー フラグがトリガーされ、例外が発生していました。これは r614 で修正され、現在展開されています。checkedConv_Ovf_I1sbyte

于 2012-12-31T08:23:12.013 に答える
1

それは確かに少し奇妙です。ProtoBuf に影響を与える CLR には違いがある可能性があります (たとえば、CLR には多数の異なる GC が付属しています)。2 台のマシンの Machine.config ファイルを比較すると、いくつかの違いが明らかになる場合があります。

問題を解決するには、enum 自体を ProtoContract でマークし、各 enum メンバーを ProtoMember でマークしてみてください。後者では、ProtoBuf が使用する Value プロパティを設定できます。DataFormat を Fixed に設定して、デフォルトよりもうまく機能するかどうかを確認することもできます。

ここでいくつかの例を見つけることができます。

于 2012-12-27T04:20:51.833 に答える