在C#中,我有一个声明为:
的属性public fixed byte foo[10]
在客户端代码中,我看到它使用此函数转换为字符串:
public static unsafe string GetString(byte* byteArray)
{
return new String((sbyte*)byteArray);
}
在IronPython打印中,它给了我一个字符串类型:
>>> print obj.foo
Baz+<foo>e__FixedBuffer1
尝试使用转换功能会出错。
>>> print GetString(obj.foo)
expected Byte*, got <Foo>e__FixedBuffer1
在IronPython中读取此属性的正确方法是什么?
答案 0 :(得分:6)
.NET中的固定字段非常特殊。您拥有的固定字段(public fixed byte foo[10]
)将被编译为特殊的嵌套结构,并且固定字段的类型将更改为该嵌套结构。简而言之,这个:
public fixed byte foo[10];
获取编译成:
// This is the struct that was generated, it contains a field with the
// first element of your fixed array
[CompilerGenerated, UnsafeValueType]
[StructLayout(LayoutKind.Sequential, Size = 10)]
public struct <foo>e__FixedBuffer0
{
public byte FixedElementField;
}
// This is your original field with the new type
[FixedBuffer(typeof(byte), 10)]
public <foo>e__FixedBuffer0 foo;
您可以使用ILSpy等工具自行查看。
现在,如果您在C#中的代码有一行GetString(obj.foo)
,则会将其编译为:
GetString(&obj.foo.FixedElementField);
因此它从字面上获取数组的第一个元素的地址,并将其作为参数传递给方法(因此GetString
参数的类型正确,byte*
)。
当您在IronPython中使用相同参数调用相同方法时,参数类型仍然是您的字段的类型:<foo>e__FixedBuffer0
,无法转换为byte*
(显然)。调用此方法的正确方法是执行与C#编译器相同的替换 - 获取FixedElementField
的地址并将其传递给GetString
,但不幸的是,Python(据我所知) )与C#中的&
运算符没有模拟。
结论是:您不能直接从IronPython访问固定字段。我想说你最好的选择就是采用“代理”方式:
public string GetFooString(Baz baz)
{
return new string((sbyte*)baz.foo);
}
PS我不是IronPython专业版,所以也许有一种超级方式可以直接访问foo prop,但我只是不知道如何。