Как использовать Protobuf-Net с MonoTouch? - PullRequest
2 голосов
/ 28 октября 2011

Кому-нибудь удалось это сделать?

Я попробовал подход, предложенный здесь , но независимо от того, как я генерирую предварительно скомпилированный сериализатор, mtouch не может скопировать его в комплект приложения, что приводит к исключению времени выполнения.Я думаю, что это происходит из-за того, что полученный бинарный файл может быть несовместим с MonoTouch.

Я пробовал следующее:

1) Я использовал предоставленные iOs и Mono бинарные файлы, включенные в последнюю версию (r450 какна этот раз) сборка для генерации предварительно скомпилированного сериализатора.

2) я использовал исходный код для создания двух разных сборок, созданных для MonoTouch.Первая сборка строится с использованием символов FEAT_SAFE; MONOTOUCH; NO_RUNTIME, а вторая - с использованием символов FEAT_SAFE; MONOTOUCH; FEAT_COMPILER.Я определил символ MONOTOUCH и использовал его так же, как используется символ MONODROID (см. Файл CallbackAttribute.cs и Helpers.cs в источнике protobuf-net).

Я использовал эти две сборки и попытался сгенерироватьпрекомпилированный сериализатор из приложения MonoTouch в симуляторе.

Но независимо от того, какую версию прекомпилированного сериализатора я использую, сборка по-прежнему не включена в комплект приложения, при этом mtouch выдает: «Warning: Library» MyLibrary.dll "отсутствует в комплекте приложений, не может извлечь содержимое", несмотря на то, что я ссылаюсь на него в моем коде .

Ответы [ 3 ]

3 голосов
/ 01 ноября 2011

Я наконец получил это. Кажется, что когда фактическое имя сборки отличается от имени файла, в котором оно содержится, mtouch не включит его в комплект приложения. И это происходило в моем случае. Я создаю сборку, как это:

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

Таким образом, учитывая, что Protobuf-Net устанавливает имя сборки для первого параметра этого метода и сохраняет его в имени файла, заданном вторым параметром, mtouch не сможет включить его в комплект приложения.

Однако я хотел сохранить свое пространство имен, чтобы поиграться с исходным кодом Protobuf-Net, чтобы сгенерировать сборку, подобную этой:

  • Путь к файлу: указывается в качестве второго параметра;
  • Имя сборки: Path.GetFileNameWithoutExtension (path);
  • Имя модуля: Path.GetFileName (путь).

В настоящее время я не выполняю никаких проверок пути, но мне пока не нужно этого делать.

И вуаля: образец работает как на симуляторе, так и на устройстве.

И последнее, но не менее важное: я не знаю, должен ли так себя вести mtouch или это ошибка. Я, однако, подам отчет об ошибке против него.

0 голосов
/ 22 июня 2017

Да, мы используем его в проекте с 2012 года для повышения производительности по сравнению с сериализацией XML.Главным образом потому, что службы RESTFul, которые мы имели в то время, не могли выполнять JSON размером более 1 МБ для некоторых файлов.На этом этапе в 2017 году нам было бы намного проще использовать JSON вместо дополнительных хлопот по созданию пользовательских сериализаторов для каждого объекта.

0 голосов
/ 29 октября 2011

Я только получил его для работы на симуляторе.Я создал сборку настраиваемой сериализации в 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-программа для:

  • Декомпиляция DLL -> IL
  • Исправление IL
  • Компиляция IL -> DLL

Вотscript:

#!/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";
}

Возможно, я просто пропустил правильный способ вызова Compile (), и мой хак не нужен.

Сборка отлично работала на симуляторе Windows и iOS.Но затем он выдал ошибку нарушения JIT во время выполнения на устройстве.Я только что создал вопрос SO:

Ошибка компиляции JIT с protobuf-net на устройстве MonoTouch / iOS (iPhone / iPad)

Я пытался использовать MonoDevelop на Mac w/ стандартный консольный проект, чтобы сначала создать сборку сериализации.У меня были некоторые проблемы, но, честно говоря, я был сонным и раздражительным, и это могло быть ошибкой пользователя, и я быстро решил перейти на Windows, поскольку в моем проекте есть другие компоненты, которые я там разрабатывал.

Я использовал.Проекты NET 4.0 на Windows и все работало нормально.Мне просто нужно было создать облегченную версию двух библиотек только для MT, чтобы я мог получить доступ к классам, которые будут сериализованы.

...