2014-09-21 49 views
0

我有以下的PInvoke :(CC#的PInvoke不改变对象

[DllImport("chess_api.dll", CallingConvention = CallingConvention.Cdecl)] 
static extern void InitBoard([MarshalAs(UnmanagedType.LPArray, SizeConst = 64)]sPiece[] board); 

C

__declspec(dllexport) void InitBoard(sPiece board[8][8]); 

在InitBoard功能,基质变化的值,但在打电话给PInvoke后我不要看到变化。

sPiece[] board = new sPiece[64]; 
InitBoard(board); 
//Here the values ​​of the board is still initialized (as before the function call) at default values 

我试图将变量更改为ref(虽然它已经引用),但它卡住程序的函数被调用时,所以我不认为这是解决方案。

我花了一段时间才到这里(我对这个主题感兴趣)我很乐意帮助!

编辑:

sPiece在C:

typedef struct Piece 
{ 
    ePieceType PieceType; //enum 
    ePlayer Player; //enum 
    int IsFirstMove; 
} sPiece; 

sPiece在C#:

[StructLayout(LayoutKind.Sequential)] 
public struct sPiece 
{ 
    public ePieceType PieceType; 
    public ePlayer Player; 
    public int IsFirstMove; 
} 
+0

'sPiece'是什么? (在C&C#中) – SLaks 2014-09-21 04:38:51

+0

@SLaks。我在这个问题上加了这个。 OMG !! – 2014-09-21 04:42:11

回答

2

也许你是失败调用函数之前分配内存。

sPiece[] board = new sPiece[64]; 
InitBoard(board); 

声明函数是这样的:

[DllImport("chess_api.dll", CallingConvention = CallingConvention.Cdecl)] 
static extern void InitBoard([Out] sPiece[] board); 

默认编组为[In]。虽然由于你的结构体是blittable,你传递的数组是固定的,并且调用的行为就像是[In,Out]一样。所以我认为如果你愿意,你可以省略[Out],但是如上所述它更清楚。

如果您愿意,您可以添加UnmanagedType.LPArray选项,但不需要。

+0

OMG !! 它终于奏效!非常感谢你! – 2014-09-21 06:25:12

+0

打败了我一拳...以及有关此类功能的更多信息,MSDN有一个很好的写法[这里](http://msdn.microsoft.com/en-us/library/hk9wyw21(v = vs。 110)的.aspx) – ryrich 2014-09-21 06:25:34