[英]PInvoke has unbalanced the stack
我正在嘗試在C#項目中使用C DLL。
我在C中有一個功能:
extern __declspec(dllexport) void InitBoard(sPiece board[8][8]);
sPiece結構:
typedef struct Piece
{
ePieceType PieceType; //enum
ePlayer Player; //enum
int IsFirstMove;
} sPiece;
我在C#中有PInvoke:
[DllImport("chess_api.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
static extern void InitBoard([MarshalAs(UnmanagedType.LPArray, SizeConst = 64)]ref sPiece[] board);
C#上的sPiece結構:
[StructLayout(LayoutKind.Sequential)]
public struct sPiece
{
public ePieceType PieceType;
public ePlayer Player;
public int IsFirstMove;
}
當我運行PInvoke時,出現以下錯誤:
調用PInvoke函數'Chess!Chess.Main :: InitBoard'會使堆棧不平衡。 這可能是因為托管PInvoke簽名與非托管目標簽名不匹配。 檢查PInvoke簽名的調用約定和參數是否與目標非托管簽名匹配。
我嘗試將調用約定更改為Cdecl
,但是當我運行它時,VS卡住了。
我應該做些什么?
你有兩個問題。 首先,您使用了錯誤的調用約定。 非托管函數使用cdecl,因此您需要托管函數來匹配它。
另一個更具挑戰性的問題是二維陣列。
void InitBoard(sPiece board[8][8]);
您不能使用p / invoke封送二維數組。 您需要切換到一維數組:
void InitBoard(sPiece board[]);
托管方如下所示:
[DllImport("chess_api.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void InitBoard(sPiece[] board);
在實現內部,您可以訪問以下元素:
要將行/列對轉換為線性索引,請使用以下關系:
index = row*8 + col;
請注意,我也刪除了SetLastError
的設置,因為我非常懷疑您的函數會調用SetLastError
。
看一下這個討論:
也許問題出在調用約定上。
...
顯然在函數原型中添加
__std
並聲明對其進行修復。 謝謝
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.