2012-04-12 31 views
3

在C#中我有一个属性声明:如何从IronPython中的公共固定字节读取数据?

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

什么是cchar?我无法找到它应该是什么的参考。还是你的意思是char? – 2012-04-12 15:19:58

+0

cchar是字节,他忘记了用cchar = System.Byte;在问题中。 用公共固定字节foo代替他的公共固定cchar foo [10] [10] – Joe 2012-04-12 19:58:43

+0

我改变了使用'byte'的问题。 – 2012-04-12 21:26:40

回答

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的支柱,但我只是看不到如何。

相关问题