2012-02-17 3 views
0

問題ことができます:私は成功したルート要素だけでなく、アンマネージコードへの配列要素を持つ構造体をマーシャリングすることができますが、バックルート要素のデータを取得することはできませんはモノラルで、アンマネージコードからではないアンマーシャリング構造体

(配列要素が来ます正しく戻る)。私は数多くのアプローチを試しましたが、それまでには何もできませんでした。以下は、最も単純なものです。

私は

実装;-)を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; 
<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#1から呼び出さ。

Iはまた、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);  

そしてこの1つはリターン時にひどくクラッシュ(ただしログはネイティブコードが実行されたことを示し、ネイティブ側の正しい値を印刷)。

私は属性デコレータなどで他の順列を試しましたが、モノラルコンパイラは、必要でなかったように一部の属性を削除することを提案しました。

私はこの2日間、私の頭の中で頭を悩ましています。どんな助けでも大歓迎です!

答えて

2

私はこれを試していないが、これは私が最初にこれを行うために試してみた方法です:

[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; 
+0

ありがとうRolf。面白いのは、頂点配列がすでに動作していることです。構造体のintはそうではありません。あなたの提案された変更では、私はverticeCountがどのようにマーシャリングされるかに何の変化も見ませんか?乾杯! –

+0

refパラメータは、[In、Out、MarshalAs(UnmanagedType.LPStruct)]パラメータと同じ方法でマーシャリングされるとは限りません:) –

+0

しかし、私はMarshal.AllocHGlobalをすべて実行する必要があると言っていますか?例えば。 MeshDataはMarshal.AllocHGlobalを取得し、頂点配列も別のものを取得しますか? –

関連する問題