3

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でこの属性を読み取る正しい方法は何ですか?

4

1 に答える 1

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に渡しますが、残念ながら、Pythonには(私の知る限り)の演算子にGetString類似したものがありません&C#。

結論は次のようになります。IronPythonから固定フィールドに直接アクセスすることはできません。私はあなたの最善の策は次のような「プロキシ」メソッドを持つことだと思います:

public string GetFooString(Baz baz)
{
    return new string((sbyte*)baz.foo);
}

PS私はIronPythonプロではないので、fooプロップに直接アクセスするためのスーパーウェイがあるかもしれませんが、その方法がわかりません。

于 2012-04-18T12:07:09.783 に答える