Protobuf-NetをMonoTouchで使うには?

実際にこれを達成した人は誰ですか?

私はこのアプローチを試しました。 here を参照してください。しかし、プリコンパイルされたシリアライザをどのように生成しても、mtouchはそれをアプリケーションバンドルにコピーできないため、ランタイム例外が発生します。これは、結果のバイナリがMonoTouchと互換性がないために起こると思います。

私は次のことを試しました:

1)プリコンパイルされたシリアライザを生成するために、最新のビルド(今回はr450)に含まれている、提供されているiOsとMonoバイナリを使用しました。

2)MonoTouch用に構築された2つの異なるアセンブリを生成するためにソースコードを使用しました。最初のアセンブリはシンボルFEAT_SAFE; MONOTOUCH; NO_RUNTIMEを使用して作成され、2番目のアセンブリはシンボルFEAT_SAFE; MONOTOUCH; FEAT_COMPILERを使用して作成されます。私はシンボルMONOTOUCHを定義し、MONODROIDシンボルが使用されているのと同じように使用しました(protobuf-netソースのファイルCallbackAttribute.csとHelpers.csを参照)。

私はこの2つのアセンブリを使用し、シミュレータのMonoTouchアプリケーションからプリコンパイルされたシリアライザを生成しようとしました。

しかし、私が使用しているプリコンパイルされたシリアライザのバージョンに関係なく、アセンブリはまだアプリケーションバンドルに含まれていません。「警告:ライブラリ 'MyLibrary.dllはアプリケーションバンドルにありません。コンテンツを抽出できません」という事実にもかかわらず私は自分のコードで参照しています

2
私は、それについての「はい」の報告(すなわち、MonoTouchでのうまくいった使用)の報告をたくさん聞いた。残念ながら、私はMacがないので、私はこれを直接調査することはできません。
追加された 著者 Marc Gravell,
@alexb少し古い今、私は人々の範囲を扱っていたここに戻る(引用したものだけではない)、私は電子メールで直接番号を持っている(しかし、実際にはそれらを共有することはできない)。しかし、ハードウェアの変更によって現在の状態を確認することはできません。
追加された 著者 Marc Gravell,
bugzilla.xamarin.comのバグレポートに記入して、使用しているソリューションを添付してください(つまり、アセンブリが参照されて使用されているが、接触が処理できない場所が示されている)。
追加された 著者 poupou,
protobufを使用するアプリケーションの要件ですか、一般的なシリアル化ソリューションを探していますか?私は、json.netに切り替える前に、protobufを動作させようとすることを含め、いくつかのシリアライズ戦略を試みました。これをクライアント側とサーバー側の両方で使用すると、非常に複雑なクラスを直列化することに成功しました。
追加された 著者 competent_tech,
あなたは私をそれを稼働させることができた人に教えてもらえますか?
追加された 著者 AlexB,
@competent_tech JSONは実際には汎用のシリアル化フォーマットです。しかし、MQTTを使用してリアルタイムのデータ(GPSの位置など)を送信する必要のある特定のシナリオでは、protobufが必要です
追加された 著者 AlexB,

3 答え

私はついにそれを得た。実際のアセンブリ名が含まれているファイル名と異なる場合、mtouchはそれをアプリケーションバンドルに含めません。それは私の場合に起こっていた。私はこのようなアセンブリを生成しています:

model.Compile("Taxi.ProtoBufSerializers.MQTTContractsSerializer", "MQTTContractsSerializer.dll");

したがって、Protobuf-Netがアセンブリ名をこのメソッドの最初のパラメータに設定し、2番目のパラメータで指定されたファイル名に保存すると、mtouchはそれをアプリケーションバンドルに含めることに失敗します。

しかし、私はProtobuf-Netのソースコードを使って次のようなアセンブリを生成するように名前空間を維持したかったのです。

  • ファイルパス:2番目のパラメータとして指定します;
  • アセンブリ名:Path.GetFileNameWithoutExtension(path);
  • モジュール名:Path.GetFileName(path)。

現時点ではパスの検証は行っていませんが、まだこれを行う必要はありません。

また、サンプルはシミュレータとデバイスの両方で動作します。

最後になりましたが、これはmtouchが動作するかどうか、またはバグかどうかはわかりません。私はそれに対してバグレポートを提出します。

3
追加された
バグレポートを記入してください:)そして、あなた自身の答えを「回答済み」にすることができますので、誰もがそれを探しているので、質問された質問に対する解決策があることが分かります。
追加された 著者 poupou,

私はシミュレータ上で動作するようになっただけです。私はVS.NET 2010でカスタムシリアル化アセンブリを作成しました。作成したIL/DLLが間違った名前空間を持っていたという問題がありました。私はこのような何かをした:

model.Compile("X.Y.Serializer.MySerializer", "X.Y.Serializer.dll")

しかし、ILは次のようなものでした:

.assembly X.Y.Serializer.MySerializer
{
   .hash algorithm 0x00008004
   .ver 0:0:0:0
}
.module X.Y.Serializer.MySerializer

私。クラス名はアセンブリ名に含まれていました。

だから、私はperlプログラムを書いて:

  • Decompile DLL -> IL
  • Fix IL
  • Compile IL -> DLL

ここにスクリプトがあります:

#!/usr/bin/perl

# Usage: fix-protobuf-assembly assembly bad-namespace
#
# Example: fix-protobuf-assembly X.Y.Serializer.dll X.Y.Serializer.MySerializer
# X.Y.Serializer.MySerializer gets converted to X.Y.Serializer

use strict;
use File::Slurp;
use Cwd;

print "Current directory is " . getcwd() . "\n";
my $asm_file = shift || die "missing assembly file";
my $bad_ns = shift || die "missing namespace";

die "no such file '$asm_file'" if (! -f $asm_file);

my $il_file = $asm_file;
$il_file =~ s#dll$#il#;

Run("ildasm /out=$il_file $asm_file");
my $il = read_file($il_file) || die "error reading $il_file: $!";

my $ns = $bad_ns;
$ns =~ s#\.[^.]+$##;
if (($il =~ s#(\.assembly|module) $bad_ns#$1 $ns#g) == 0)
{
   die "$bad_ns not found in input dll; aborting";
}
write_file($il_file, $il);

Run("ilasm /dll $il_file");

sub Run
{
   my($command) = @_;

   warn "Running $command ...\n";
   system($command) && die "error running last command; bailing out";
}

たぶん、私はちょうどコンパイル()を呼び出すための適切な方法を見逃して、私のハックは不要です。

アセンブリは、WindowsとiOSシミュレータで正常に動作しました。しかし、その後、デバイス上で実行時JITコンパイル違反エラーが発生しました。私はちょうどSOの質問を作成しました:

protobuf-netのJITコンパイルエラーMonoTouch/iOSデバイス(iPhone/iPad)

私は、シリアル化アセンブリを最初に作成するために、標準コンソールプロジェクトのMacでMonoDevelopを使用しようとしました。私はいくつかの問題がありましたが、私のプロジェクトには私がそこで開発した他のコンポーネントがあるので、私は眠くて悲しかったし、ユーザーエラーかもしれませんでした。

私はWindows上で.NET 4.0プロジェクトを使用し、すべて正常に機能しました。私は、シリアライズされるクラスにアクセスできるように、2つのMT専用ライブラリの軽量版を作成しなければなりませんでした。

0
追加された
MonoTouchのProtoBuf-Net用スタンドアロンサンプルを github.com/t9mike/ProtoBuf1 に作成しました。これはシミュレータ上で動作しますが、デバイスに問題があります。詳細は protobufのJITコンパイルエラーMonoTouch/iOSデバイス(iPhone/iPad)のネット。
追加された 著者 t9mike,

はい、私たちは2012年以降、XMLシリアル化のパフォーマンスを向上させるためにこのプロジェクトをプロジェクトで使用しています。ほとんどの場合、当時のRESTFulサービスでは、ファイルのサイズが1MBを超えるJSONを実行できなかったためです。 2017年の時点で、各オブジェクトのカスタムシリアライザを構築するという面倒な作業ではなく、JSONの使用がずっと簡単になりました。

0
追加された