C #: указатель на структуру внутри структуры

2

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

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;
}

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

Невозможно принять адрес, получить размер или объявить указатель на управляемый тип ('Assimp.aiNode')

Любые идеи о том, как решить эту проблему?

Теги:
marshalling

2 ответа

3
Лучший ответ

Это может сильно осложниться в зависимости от того, что вы пытаетесь сделать. Однако, поскольку вы работаете, это может помочь вам объявить каждый из указателей в коде С#, как это. Он использует очень полезный IntPtr, который был описан здесь ранее сегодня.:)

Обратите внимание, что это не поможет магическим образом заставить ваш код работать. Мне нужно будет увидеть гораздо больше того, что происходит, прежде чем я могу дать вам информацию об этом.

public struct aiScene
{
    public uint Flags;
    public IntPtr RootNode;
    ...
}
  • 0
    Господи, что за изврат...лучше взять C++\CLI. Большое спасибо за ответ!
  • 0
    Использование IntPtr для всех этих типов быстро становится кошмаром, поскольку нет проверки типов, разделяющей различные типы IntPtr. Лучше использовать небезопасную структуру . (определите каждый тип, такой как aiNode, как тип структуры, затем используйте небезопасный aiNode )
0

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

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

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

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню