- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试在 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/
这是我尝试在 C# 中使用的头文件签名和 C 代码: __declspec(dllexport) emxArray_real_T *emxCreateWrapper_real_T(real_T *da
我的项目在 .NET Frame work 3.5 中运行成功且没有错误。但是,当我将它定位到 .NET Frame work 4 时。我得到了错误: “对 PInvoke 函数的调用使堆栈不平衡。这
我在非托管 DLL 中有一个非常简单的函数,但我没有从它获得正确的返回值。 我可以确认通用 PInvoke 机制正在使用我的 C DLL 中的一个函数: /* Return an integer */
使用 PInvoke 时可能会发生哪些异常,或者所有错误均由方法返回值处理,并且由开发人员检查并在需要时引发异常? 最佳答案 对于 P/Invoke,可以肯定地说您需要处理两种类型的错误。 P/Inv
我正在尝试为 modbusm.dll (win-tech.com/html/mbusocx.htm) 创建一个包装器 C# 文件,为此我使用 dumpbin 输出。 文件 modbusm.dll 的转
我正在尝试使用 PInvoke 绑定(bind)此 C 函数。 bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool edi
我目前正在尝试通过 C# pinvoke 使用 SendMessage 从子窗口获取一些文本。但是,我之前对窗口句柄进行硬核化的尝试失败了,因为该值在应用程序启动时发生了变化。有没有办法可靠地获取这个
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
考虑以下 C 函数: void get_lib_version(const char **ver_string); 如何使用 PInvoke 正确编码它?文档说它返回一个指向静态字符串的指针。我认为这
我有个问题,很奇怪。当我在 PInvoke 中使用下一个结构时,它正在工作,但是当我将它更改为类时,它不起作用。 我的 C#: [StructLayout(LayoutKind.Sequential)
我在 C++ 原生 dll 中有以下函数,我想在 C# 应用程序中使用它。 DWORD __cdecl Foo( LPCTSTR Input,
似乎有多种方法可以做到这一点,但我尝试过的示例对我不起作用。 我在某处读到,使用不安全指针是获得需要指针的更复杂结构的方法。 (对不起,我没能再次找到来源) 我最近的尝试看起来像这样: unsafe
我正在尝试在 C++ 中创建一个简单的 dll,并使用 PInvoke 从 C# 中调用它。我想传入一个字节数组,对其进行一些操作,然后发回另一个字节数组。我想我会传入框架和大小,然后创建一个非托管的
我正在尝试使用 P/Invoke 从 C# 调用 C++ 函数。 [DllImport(PATH)] public static extern int PQunescapeByteaWrapper(
我正在尝试使用 GetFileInformationByHandle 函数获取 FILE_ID_BOTH_DIR_INFO。调用后我的所有值都设置为零。 我收到 win32 错误消息: ERROR_B
我有以下 C 代码: const BYTE* Items[3]; Items[0] = item1; Items[1] = item2; Items[2] = item3; int result =
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我有以下 PInvoke:(C 到 C#) [DllImport("chess_api.dll", CallingConvention = CallingConvention.Cdecl)] stat
我正在尝试在 C# 项目中使用 C DLL。 我在 C 中有一个函数: extern __declspec(dllexport) void InitBoard(sPiece board[8][8]);
我如何在 C# 中使用这个 dll 函数?我尝试了以下但出现错误。“外部组件抛出异常。” 我第一次用 C# 和 Delphi 做这个 PInvoke 的东西。 function HTTPGET(loc
我是一名优秀的程序员,十分优秀!