在C#和IronPython之间传递pickle字符串

时间:2011-11-18 18:47:17

标签: c# .net ironpython pickle

我写了一个IronPython包来做一些数据处理,现在我把它包装在一个C#应用程序中。应用程序的部分功能是保存项目的状态,然后再恢复该保存的状态。

我正在使用IronPython中的pickle模块从我的自定义包中保存类的对象。在我用C#进行包装之前,这没有问题:我使用pickle.dump()函数将对象序列化为文件。现在我想使用pickle.dumps()函数将对象序列化为字符串,然后将该字符串传递给C#对象并使用XmlSerializer序列化 THAT 对象。

序列化似乎有效,但反序列化失败了:C#获取反序列化的字符串并将其传递给IronPython,IronPython应该能够使用pickle.loads()函数重新构建原始对象,而是引发此错误:

System.Collections.Generic.KeyNotFoundException {"ô"}
你可以帮我解决这个问题吗?我有两个理论:

  1. 也许IronPython和C#之间或C#,IronPython之间的字符串编码与pickle模块所期望的字符串编码有所不同?

  2. 首先不是整个字符串被序列化,所以我只是把废话传递给pickle.loads()

  3. 我的证据使我了解这些理论:

    1. 错误消息(ô)中缺少的密钥看起来像是一些unicode-as-ASCII-text。

    2. 如果我中断执行(在Visual Studio 2010的调试模式下)并在将字符串传递给IronPython以进行取消之前查看该字符串,我看到的内容不足以表示整个对象。但它可能只是达到Visual Studio调试器将显示的限制。

    3. 提前致谢!

1 个答案:

答案 0 :(得分:0)

简短的回答:protocol=-1的酸洗适用于我,默认的人类可读协议没有。

答案很长:看起来理论#1基本上是正确的。我使用大型numpy数组的字典来存储我的数据,甚至使用默认的“人类可读”的酸洗协议,它们被腌制成类似二进制的形式。请注意从底部开始的第四行(这是从可以成功取消选择的pickle文件中提取的,但它会让我知道我在文件中看不到的内容):

(g10
(I0
tp25
g12
tp26
Rp27
(I1
(I2
tp28
g19
I00
Vq=\u000a×£°(@R¸\u2026ëQ.@
p29
tp30
bssb.

这可能会导致

链中某处出现错误
  1. 在IronPython中挑选一个字符串
  2. 将该字符串传递给C#对象
  3. 使用XmlSerializer序列化该对象
  4. 反序列化xml以获取C#对象
  5. 将代表pickle对象的字符串传递回IronPython
  6. 取消IronPython中的字符串
  7. 错误发生的地方,我还不知道。我通过使用protocol=-1来挑选IronPython对象解决了这个问题,该对象将对象转换为可以在此过程中存活的二进制乱码字符串。