【问题标题】:Protbuf-net Compiling to DLL string[] causing corrupt dllProtobuf-net 编译为 DLL 字符串 [] 导致损坏的 dll
【发布时间】:2014-06-25 09:09:24
【问题描述】:

这是我的代码:

using ProtoBuf;

[ProtoContract]
[ProtoInclude(500, typeof(SampleClassDrv))]
public class SampleClass
{
    [ProtoMember(1)] public int theInt;
    [ProtoMember(2)] public string[] items;
    public SampleClass(){}
    public SampleClass(int c) {this.theInt = c;}
}

[ProtoContract]
public class SampleClassDrv : SampleClass
{
    [ProtoMember(1)] public int theOtherInt;
    public SampleClassDrv(){}
    public SampleClassDrv(int b):base(1){this.theOtherInt=b;}
}

要编译我的 DLL,我运行以下代码:

RuntimeTypeModel rModel = TypeModel.Create();
rModel.AllowParseableTypes = true;
rModel.AutoAddMissingTypes = true;

rModel.Add(typeof(SampleClass), true);
rModel.Add(typeof(SampleClassDrv), true);
rModel.Compile("MySerializer", "MySerializer.dll");

最后我应该能够像这样从 dll 中通过 RuntimeTypeModel 进行初始化:

MySerializer serializer = new MySerializer();
serializer.Serialize(stream, object);

但 Unity 抛出以下异常

Internal compiler error. See the console log for more information.
[...]
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.

如果我回去删除这条线就足够有趣了

[ProtoMember(2)] public string[] items; 

它按预期工作......

还值得注意的是,如果在添加类而不是尝试使用 dll 之后使用 RunTimeModel,则可以按预期工作。

我的环境:

  • Unity3D 4.3.4
  • Protobuf-net r668
  • 在 Full/unity 中使用 protbuf-net.dll

如果有人能以我的方式指出错误,我将不胜感激。

编辑

根据 Flamy 的建议,我将表单 string[] 更改为 List

[ProtoMember(2)] public List<string> items;

遗憾的是错误仍然存​​在。

另一个注意事项

我还决定使用 dll 反编译器来查看发生了什么。在删除“string[] items”变量之前,我无法反编译 dll。

已解决

我认为这与使用 Unity3D 编译 DLL 的一些问题有关。

当我使用上面显示的代码在 Visual Studios 中创建项目时,一切似乎都按预期工作。这是一种解脱,因为如果 protobuf 无法序列化 string[],这似乎将是一个大问题。

我按照 BCCode 提供的文章设置 Visual Studio 项目并编译 DLL。

现在我需要做的就是用我的大型项目创建 dll! 手指交叉

感谢大家的帮助!

【问题讨论】:

  • 这可能与您的问题无关,但据我了解,theOtherInt 将在基类中影响theInt。如果这是实际类的代表,您可能需要更改派生类的成员索引,以使它们不会与基类的成员索引发生冲突。
  • 我找不到任何明确说明这一点的地方,但它确实是有道理的。也许@MarcGravell 可以验证。
  • 我的印象是索引只需要每个类库都是唯一的,但如果你是正确的,那是我的代码中的一个大错误,我将更新我的实际代码以反映你的建议注意安全。谢谢!

标签: c# serialization dll unity3d protobuf-net


【解决方案1】:

使用二进制序列化或使用二进制格式(在本例中为protobuff)的序列化方法对字符串数组进行序列化总是会导致很多问题。原因是 String 本身是一个字符数组,它没有定义的大小,这意味着它不知道一个字符串在哪里结束,下一个从哪里开始......通常我们一个接一个地序列化字符串数组而不是整个数组。所以我建议你使用一个可以做到这一点的属性(希望 protobuff 接受属性上的属性!)或者创建一个字符串列表(虽然我还没有测试过它应该可以工作!)

【讨论】:

  • 我尝试了您的建议并将 string[] 更改为 List 但没有运气。感谢您的尝试!
  • String[] 被隐式转换为重复值,通常在 Protobuf-Net 中使用是安全的。它们的处理方式与List&lt;string&gt; 没有区别。
  • 另请注意,实际的序列化工作正常,直到编译为 dll。
【解决方案2】:

您的参考资料正确吗? %project dir%\Library\ScriptAssemblies\Assembly-CSharp.dll

也看看这里: http://purdyjotut.blogspot.com/2013/10/using-protobuf-in-unity3d.html?m=1

【讨论】:

  • 在 Mac 上开发,参考由 Unity 处理。我认为他们是正确的。如果我只是缺乏这方面的知识,请告诉我。现在要浏览那篇文章。谢谢!
  • 浏览了这篇文章,结果发现我在开始时使用了类似的,但与我在环境之外所做的似乎没有什么不同。所以我要跳上windows并尝试在那里编译dll。
  • 我将您的解决方案标记为解决方案,因为它引导我找到了正确的答案。更新了细节问题......在Unity3d中编译dll存在一些问题。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-06
相关资源
最近更新 更多