Невозможно распаковать структуру из неуправляемого кода в Mono - PullRequest
0 голосов
/ 17 февраля 2012

Проблема:

Я могу успешно преобразовать структуру с корневыми элементами, а также с элементами массива в неуправляемый код, но не могу вернуть данные корневых элементов (элементы массива возвращаются правильно). Я попробовал несколько подходов, но ни один из них не сработал. Вот самый простой из приведенных ниже.

Я прочитал по адресу http://www.mono -project.com / Interop_with_Native_Libraries и думаю, что все делаю правильно (но, очевидно, нет; -)

Осуществление:

C # декларации:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct Vector3
{
    public float x;
    public float y;
    public float z;
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct MeshData
{
    [MarshalAs(UnmanagedType.LPArray)]
    public Vector3[] vertices;
    public int verticeCount;
}

[DllImport("MeshPlugin")]
private static extern bool ImportMesh([In, Out, MarshalAs(UnmanagedType.LPStruct)] MeshData meshData);

Собственные объявления C:

#pragma pack(1)
typedef struct VECTOR3
{
    float x;
    float y;
    float z;
} VECTOR3;

#pragma pack(1)
typedef struct MESHDATA
{
    VECTOR3 *vertices;
    int verticeCount;
} MESHDATA;

Вызывается из C # примерно так:

<defined vertices and length...>

MeshData meshData = new MeshData();
meshData.vertices = mesh.vertices; // note that vertices[0].x = 111
meshData.verticeCount = 1;
ImportMesh(meshData); // calls native function
Debug.Log(meshData.vertices[0].x); // prints  222 which is correct, so array got marshaled back okay
Debug.Log(meshData.verticeCount); //  **prints 1 which is incorrect** so the int element did not come back okay

Собственная реализация:

bool ImportMesh(MESHDATA *meshData)
{
    printf("%f", meshData->vertices[0].x); // prints 111 which is correct
    meshData->vertices[0].x = 222; // change to see if it gets back okay
    printf("%d", meshData->verticeCount); // prints 1 which is correct
    meshData->verticeCount = 2; // change to see if it gets back okay
    return true;
}

Проблема в том, что значения структуры массива возвращаются правильно, а основные элементы структуры - нет.

Я тоже пробовал это в C #:

[DllImport("MeshPlugin")]
private static extern bool ImportMesh(IntPtr meshData);

int size = Marshal.SizeOf(typeof(MeshData));
IntPtr pMeshData = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(meshData, pMeshData, false);
ImportMesh(pMeshData);
meshData = (MeshData)(Marshal.PtrToStructure(pMeshData, typeof(MeshData)));
Marshal.FreeHGlobal(pMeshData);     

И эта ошибка дает сбой при возврате (но журнал показывает, что собственный код выполнен и напечатал правильные значения на собственной стороне).

Я пробовал другие перестановки с декораторами атрибутов и т. Д., Но моно-компилятор предложил удалить некоторые атрибуты, поскольку они не были нужны, поэтому я и сделал.

Я уже 2 дня гуглю и ломаю себе голову, и любая помощь очень ценится!

1 Ответ

2 голосов
/ 17 февраля 2012

Я не пробовал это, но вот как я бы сначала попытался это сделать:

[DllImport("MeshPlugin")]
private static extern bool ImportMesh(ref MeshData meshData);

и если он все еще не работает, я бы попытался изменить объявление структуры на:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct MeshData
{
    public IntPtr vertices;
    public int verticeCount;
}
MeshData meshData = new MeshData();
meshData.vertices = Marshal.AllocHGlobal (...);
// copy vertex data to the unmanaged array
meshData.verticeCount = 1;
...