将包含数组的C结构编组到C#
问题描述:
在 stackoverflow 社区的大力帮助下,我设法调用了本机DLL函数.但是,我不能修改 ID
或intersects
数组的值.不管我在DLL方面使用它是什么,旧值仍然存在.似乎是只读的.
With great help of the stackoverflow community, I've managed to call a native DLL function. However, I can't modify the values of ID
or intersects
array. No matter what I do with it on the DLL side, the old value remains. It seems read-only.
以下是一些代码片段:
C ++结构:
typedef struct _Face {
int ID;
int intersects[625];
} Face;
C#映射:
[StructLayout(LayoutKind.Sequential)]
public struct Face {
public int ID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 625)]
public int[] intersects;
}
C ++方法(在VS2010中类型设置为DLL):
C++ method (type set to DLL in VS2010):
extern "C" int __declspec(dllexport) __stdcall
solve(Face *faces, int n){
for(int i =0; i<n; i++){
for(int r=0; r<625; r++){
faces[i].intersects[r] = 333;
faces[i].ID = 666;
}
}
C#方法签名:
[DllImport("lib.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int solve(Face[] faces, int len);
C#方法调用:
Face[] faces = new Face[10];
faces[0].intersects = new int[625];
faces[0].ID = -1; //.. and add 9 more ..
solve(faces, faces.Length);
// faces[0].ID still equals -1 and not 666
最诚挚的问候, e.
答
您必须明确告诉pinvoke编组说需要将数组编组回去.您可以使用[In]和[Out]属性来执行此操作.像这样:
You have to tell the pinvoke marshaller explicitly that the array needs to be marshaled back. You do this with the [In] and [Out] attributes. Like this:
[DllImport("...")]
public static extern int solve([In, Out] Face[] faces, int len);