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

本文关键字:pickle 字符串 之间 IronPython | 更新日期: 2023-09-27 18:15:13

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

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

序列化似乎可以工作,但是反序列化崩溃了:c#获得反序列化字符串并将其传递给IronPython,它应该能够使用pickle.loads()函数重建原始对象,但却引发了这个错误:

System.Collections.Generic.KeyNotFoundException {"ô"}
你能帮我解决这个问题吗?我有两个理论:
  1. 也许IronPython和c#之间,或者c#, IronPython之间的字符串编码存在差异,以及pickle模块所期望的内容?

  2. 不是整个字符串首先被序列化,所以我只是传递无意义的pickle.loads()

让我得出这些理论的证据:

  1. 错误消息(ô)中缺少的键看起来像unicode解析为ascii文本。

  2. 如果我中断执行(在Visual Studio 2010的调试模式下)并在将字符串传递给IronPython进行解选之前查看字符串,我看到的长度不足以表示整个对象。但是它可能已经达到了Visual Studio调试器显示的极限。

提前感谢!

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

简短的回答:在默认的、人类可读的协议不起作用的地方,使用protocol=-1进行pickle对我来说是有效的。

长话短说:看起来理论1基本上是正确的。我使用一个大型numpy数组的字典来存储我的数据,即使使用默认的"人类可读"pickle协议,它们也被pickle为类似二进制的形式。请注意从底部开始的第四行(这是从可以成功地取消 pickle的文件中提取的,但它让我了解了我在不能取消pickle的文件中看到的内容):

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

有可能在

链的某个地方导致错误。
  1. pickle到IronPython中的字符串
  2. 将字符串传递给c#对象
  3. 用XmlSerializer序列化该对象
  4. 反序列化xml以返回c#对象
  5. 将表示pickle对象的字符串传递回IronPython
  6. 取消IronPython中的字符串

错误究竟发生在哪里,我还不知道。我通过使用protocol=-1 pickle IronPython对象来解决这个问题,它将对象转换为可以在此过程中存活的二进制乱码字符串。