【发布时间】:2018-02-21 18:42:36
【问题描述】:
我一直在调查是否有人找到任何文档或想出如何让对象池与 AoT 编译(iOS 和 WebGL for Unity 需要)一起工作。
我在这里找到了来自 Marc Gravell 的 this answer,它描述了如何让工厂使用您的对象池,但是如果您使用 AoT 预编译器并调用如下代码,这似乎不起作用:
public static T DeserializeProtoObject<T>(byte[] bytes)
{
using (MemoryStream m = new MemoryStream(bytes))
{
return (T)m_serializer.DeserializeWithLengthPrefix(m, null, typeof(T),ProtoBuf.PrefixStyle.Fixed32,0);
}
}
m_serializer 是使用预编译器创建的,代码如下:
var model = TypeModel.Create();
model.Add(typeof(PlayerUpdate), true);
model.AllowParseableTypes = true;
model.AutoAddMissingTypes = true;
model.Compile("IOGameProtoBufSerializer", "IOGameProtoBufSerializer.dll");
看起来模型有一个 SetDefaultFactory() 函数,但我不知道如何使用它。知情人士有什么建议吗?
我的下一步是下载源代码并深入研究。
感谢您的帮助。
编辑: 看起来我在从此处下载完整的 protobuf-net 存储库后找到了示例源:https://github.com/mgravell/protobuf-net
对于那些想要做同样事情的人来说,这里是实际的源代码,展示了如何使用默认构造函数的示例:
using Xunit;
using ProtoBuf;
using ProtoBuf.Meta;
using System;
using System.Threading;
using System.Reflection;
namespace Examples.Issues
{
public class SO14532116
{
[Fact]
public void Execute()
{
var model = TypeModel.Create();
model.AutoCompile = false;
model.SetDefaultFactory(typeof(SO14532116).GetMethod("ObjectMaker"));
int oldCount = Count;
Test(model, "Runtime");
model.CompileInPlace();
Test(model, "CompileInPlace");
Test(model.Compile(), "CompileInPlace");
model.Compile("SO14532116", "SO14532116.dll");
PEVerify.AssertValid("SO14532116.dll");
int newCount = Count;
Assert.Equal(oldCount + 3, newCount);
}
[ProtoContract]
public class Foo
{
[ProtoMember(1)]
public int X {get;set;}
public static Foo Create(int x = 0)
{
return new Foo(x);
}
public Foo(int x) { X = x; }
}
private void Test(TypeModel model, string p)
{
var obj = Foo.Create(123);
int oldCount = Count;
var clone = (Foo)model.DeepClone(obj);
int newCount = Count;
Assert.Equal(oldCount + 1, newCount);
Assert.Equal(123, clone.X);
}
private static int count;
public static int Count
{
get { return Interlocked.CompareExchange(ref count, 0, 0); }
}
public static object ObjectMaker(Type type)
{
object obj;
if(type == typeof(Foo))
{
obj = Foo.Create();
} else {
obj = Activator.CreateInstance(type);
}
Interlocked.Increment(ref count);
return obj;
}
}
}
【问题讨论】:
-
好的,所以在下载完整的 repo 后,我能够找到 Mark 在另一篇文章中提到的使用默认工厂的示例代码。不幸的是,我不能在这里发表评论。但只需从此处克隆 git 存储库:github.com/mgravell/protobuf-net,然后转到示例 -> 问题 -> SO14532116.cs
标签: protobuf-net