どのように私マーシャルは、鋭いCへの再帰的な構造体のですか?
-
18-09-2019 - |
質問
私は、私は基本的にはこのようになりますCシャープにマーシャリングしたい管理対象外の構造体を持っています
struct MyStruct{
/* ... some stuff ... */
int numChilds;
MyStruct *childs;
}
私は、カスタムマーシャラーを記述する必要がありますが、私は続行する方法についてはよく分からないと信じています。
解決
私は私が直接インデックス子どもたちに必要がない場合は、このように設定を使用したいです
struct MyStruct
{
/* ... some stuff ... */
int numChilds;
IntPtr childData;
public IEnumerable<MyStruct> Children
{
get
{
int elementSize = Marshal.SizeOf(typeof(MyStruct));
for (int i = 0; i < this.numChilds; i++)
{
IntPtr data = new IntPtr(this.childData.ToInt64() + elementSize * i);
MyStruct child = (MyStruct)Marshal.PtrToStructure(data, typeof(MyStruct));
yield return child;
}
}
}
}
あなたがを行う場合は、は最も簡単な方法は、(下図)メソッド
GetChild
を作成して、直接インデックス子供にする必要があります。難しい方法はIList<MyStruct>
を実装するヘルパー/ラッパークラスを作成しています。インスタンスはChildren
プロパティから返されると、その内部にはGetChild
メソッドを呼び出すことで動作します。これは、彼がそれを必要としなければならない読者への課題として残しておきます。
public MyStruct GetChild(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException("index", "The index must be >= 0.");
if (index >= this.numChilds)
throw new ArgumentException("The index must be less than the number of children", "index");
int elementSize = Marshal.SizeOf(typeof(MyStruct));
IntPtr data = new IntPtr(childData.ToInt64() + elementSize * index);
MyStruct child = (MyStruct)Marshal.PtrToStructure(data, typeof(MyStruct));
return child;
}
他のヒント
あなただけのいくつかのアンマネージ関数に渡したい場合は、
、あなただけのオブジェクトの配列へのポインタを取得するための配列を修正/危険なコードとstackallocを使用することができます。
unsafe struct Foo
{
public int value;
public int fooCount;
public Foo* foos;
}
[DllImport("dll_natv.dll")]
static extern void PrintFoos(Foo f);
public unsafe static void Main()
{
Foo* foos = stackalloc Foo[10];
for (int i = 0; i < 10; ++i)
foos[i].value = i;
Foo mainFoo = new Foo();
mainFoo.fooCount = 10;
mainFoo.value = 100;
mainFoo.foos = foos;
PrintFoos(mainFoo);
}
所属していません StackOverflow