问题:
我可以成功地将具有根元素和数组元素的结构编组为非托管代码,但无法获取根元素数据(数组元素返回正确)。我尝试了很多方法,但迄今为止都没有。这是下面最简单的一个。
我在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天,并且非常感谢任何帮助!
答案 0 :(得分:2)
我没试过这个,但这是我第一次尝试这样做的方法:
[DllImport("MeshPlugin")]
private static extern bool ImportMesh(ref MeshData meshData);
如果它仍然不起作用,我会尝试将struct声明更改为:
[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;