2009-07-19 2 views
2

Я пытаюсь использовать сортировку в C#. В C++ У меня есть эта структура:C#: Указатель на структуру внутри структуры

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 является:

[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) и т.д. Таким образом, у меня есть эта ошибка :

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. Большое спасибо за ответ! – 2009-07-19 04:27:15

+0

Использование IntPtr для всех этих типов быстро становится кошмаром, потому что нет проверки типа, разделяющей различные типы IntPtr. Лучше использовать небезопасную структуру *. (определите каждый тип, например aiNode, как тип структуры, затем используйте небезопасный aiNode *) –

0

Основная проблема, с которой вы сталкиваетесь, состоит в том, что вы определили управляемые объекты с теми же именами, что и неуправляемые типы. Типы указателей, такие как «aiNode», должны быть определены как структуры, а не классы. Вы можете определить по-разному названные классы управляемых оболочек, которые обеспечивают управляемый доступ к лежащим в основе небезопасным данным структуры. Например:

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

На высоком уровне похоже, что вы пытаетесь использовать AssImp с C#. Это можно сделать сегодня, используя assimp-net. Однако, если кто-то сталкивается с подобной ситуацией и хочет получить общий ответ.

Я настоятельно рекомендую не использовать IntPtr для чего-либо, потому что это в основном нетипизированная пустота * без проверки типа. Unsafe-struct-указатели предлагают более безопасное устранение неуправляемых типов указателей. SafeHandle - еще один вариант с лучшей безопасностью и управлением некоторыми расовыми условиями. См. my article on the topic.

Если вы буквально хотите скопировать данных из неуправляемых в управляемые земли, то для каждого типа (aiNode, aiMesh и т.д.), необходимо определить как небезопасную--структуру (в соответствии с неуправляемым макетом), и управляемый класс. Затем напишите (или сгенерируйте) небезопасный код, чтобы скопировать неуправляемое дерево в управляемые объекты. Обязательно будьте осторожны с любыми неуправляемыми объектами с несколькими ссылками.

Иногда лучшей альтернативой является создание оболочки, которая обеспечивает доступ к неуправляемым данным «на месте». Если вы делаете это «безопасно», тогда управляемые обертки должны быть тонкими объектами, которые управляют временем жизни для неуправляемых объектов и имеют свойства для доступа к их данным. В качестве альтернативы вы можете сделать это небезопасно, просто определяя небезопасные структуры и используя их в небезопасном контексте.

Смежные вопросы