gpt4 book ai didi

c# - PInvoke 使堆栈不平衡

转载 作者:太空宇宙 更新时间:2023-11-04 02:47:18 28 4
gpt4 key购买 nike

我正在尝试在 C# 项目中使用 C DLL。

我在 C 中有一个函数:

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

零件结构:

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 时,出现以下错误:

A call to PInvoke function 'Chess!Chess.Main::InitBoard' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

我尝试将调用约定更改为 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

关于c# - PInvoke 使堆栈不平衡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25951637/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com