2009-07-19 58 views
2

C#でマーシャリングを使用しようとしています。C#:構造体内の構造体へのポインタ

[StructLayout(LayoutKind.Sequential)] 
public struct aiScene 
{ 
    public uint mFlags; 
    public unsafe aiNode* mRootNode; 
    public uint mNumMeshes; 
    public unsafe aiMesh** mMeshes; 
    public uint mNumMaterials; 
    public unsafe aiMaterial** mMaterials; 
    public uint mNumAnimations; 
    public unsafe aiAnimation** mAnimations; 
    public uint mNumTextures; 
    public unsafe aiTexture** mTextures; 
    public uint mNumLights; 
    public unsafe aiLight** mLights; 
    public uint mNumCameras; 
    public unsafe aiCamera** mCameras; 
} 

しかし、この構造体の多くは、など(aiNode、aiMesh、aiLight)だから、私はこのエラーを持って管理されている。

struct aiScene 
{ 
    unsigned int mFlags; 
    C_STRUCT aiNode* mRootNode; 
    unsigned int mNumMeshes; 
    C_STRUCT aiMesh** mMeshes; 
    unsigned int mNumMaterials; 
    C_STRUCT aiMaterial** mMaterials; 
    unsigned int mNumAnimations; 
    C_STRUCT aiAnimation** mAnimations; 
    unsigned int mNumTextures; 
    C_STRUCT aiTexture** mTextures; 
    unsigned int mNumLights; 
    C_STRUCT aiLight** mLights; 
    unsigned int mNumCameras; 
    C_STRUCT aiCamera** mCameras; 
} 

ので、C#のeqvivalentがある:C++では、私は、この構造体を持っています:

Cannot take the address of, get the size of, or declare a pointer to a managed type ('Assimp.aiNode')

どのようにこの問題を解決するためのアイデアですか?

答えて

3

これは、何をしようとしているかによって非常に複雑になる可能性があります。しかし、あなたが作業しているときに、このようなC#コードの各ポインタを宣言するのに役立ちます。それはvery useful IntPtr, which was described on here earlier todayを使用します。 :)

これは魔法のようにあなたのコードを動作させることはありませんのでご注意ください。私はあなたにそれを入力する前に何が起こっているのかをもっと見る必要があります。

public struct aiScene 
{ 
    public uint Flags; 
    public IntPtr RootNode; 
    ... 
} 
+0

C++ \ CLI。C++ \ CLI。 Большоеспасибозаответ! –

+0

IntPtrの種類を区別する型チェックがないため、これらのすべての型に対してIntPtrを使用することは、まさに悪夢となります。安全でない構造体*を使う方が良いでしょう。 (aiNodeなどの各タイプを構造体タイプとして定義し、安全でないaiNode *を使用する) –

0

主な問題は、アンマネージドタイプと同じ名前の管理対象オブジェクトを定義していることです。 "aiNode"のようなポインタ型は、クラスではなく構造体として定義する必要があります。異なる名前の管理対象ラッパークラスを定義して、基礎となる安全でない構造体データへの管理されたアクセスを提供できます。例:

public struct aiNode {} 
public struct aiScene 
{ 
    public uint mFlags; 
    public unsafe aiNode* mRootNode; 
    // ... 
} 

高レベルでは、C#のAssImpを使用しようとしているようです。これは今日assimp-netを使って行うことができます。しかし、誰かがこのようなマーシャリングの状況に遭遇し、一般的な答えを求めている場合は...

タイプチェックをしていないので、基本的に型なしのvoid *なので、IntPtrを使用することを強くお勧めします。安全でない構造体ポインタは、アンマネージドポインタ型のより明確な明確化を提供します。 SafeHandleは、より良い安全性といくつかの競争条件の処理を備えた別のオプションです。 my article on the topicを参照してください。

あなたは文字通りコピーに管理する土地への非管理からのデータが必要な場合は、各タイプ(aiNode、aiMesh、など)のためにあなたが危険-構造体の両方を定義する必要があります(管理対象外のレイアウトに合わせて)、およびA管理クラス。次に、管理されていないツリーを管理対象オブジェクトにコピーするための安全でないコードを作成(または生成)します。複数の参照を持つ管理されていないオブジェクトには注意が必要です。

場合によっては、管理されていないデータに「インプレース」でアクセスするためのラッパーを記述することもできます。 「安全に」実行している場合、管理対象ラッパーは、管理対象外オブジェクトの有効期間を管理し、データにアクセスするためのプロパティを持つ薄型オブジェクトでなければなりません。あるいは、安全でない構造体を定義し、安全でないコンテキストでそれらを使用するだけで、安全ではありません。