PinvokeStackImbalance 发生。抛出此异常,但我不知道错误是什么?

PinvokeStackImbalance occured. This exception is thrown but i have no idea what the error is?

异常:

托管调试助手 'PInvokeStackImbalance' 在 'D:\UI_still_in_progress\user_interface\bin\Debug\WindowsFormsApplication1.vshost.exe' 中检测到问题。

基本上我的应用程序有一个用 c++ 编写的后台实时进程,它与微处理器通信。我已经设置了一个 c++ dll 文件,它允许我实时传递来自 c++ 应用程序和 c# UI 的数据。

我的问题是我必须创建一个有限状态机以确保物理设备和 C++ 应用程序都在根据 UI 中发生的事情做它们应该做的事情。所以我的目标是将表示状态的简单整数从 c# 传递到 c++。

使用以下实现,实时数据从 c++ 传递到 c# 没有问题:

c++ .h 文件片段:

extern "C" __declspec (dllexport) int grabx();
extern "C" __declspec (dllexport) void setFSMstate(int s);

C++ .cpp 文件片段:

int grabx()
{
    return x0;
}

void setFSMstate(int s)
{
    state = s;
}

c#class

public class MyDllMethods {

    [DllImport("dllTESTER.dll")]
    public static extern int grabx();

    [DllImport("dllTESTER.dll")]
    public static extern void setFSMstate(int s);
}

c# 方法调用

xx = MyDllMethods.grabx();
MyDllMethods.setFSMstate(2);

grabx()函数运行良好,我可以实时从设备读取x值。当我的 UI 移动到新屏幕时,我尝试通过将 2 传递到 setFSMstate() 来更改每个应用程序中的状态。调用此方法时会抛出异常。

我是 P/Invoke 的新手,所以如果有任何遗漏请帮忙。我可能编组错误,但我相信类型 int 在 C# 和 C++ 中是相同的?

您 运行 遇到的问题是调用约定不匹配。调用约定指定参数如何传递给函数,以及它们的 return 值如何传递回调用者。您的 C++ 函数是使用隐式调用约定 __cdecl 声明的,但 P/Invoke 的默认调用约定是 __stdcall.

要解决此问题,您只需更改 P/Invoke 配置:

[DllImport("dllTESTER.dll", CallingConvention = CallingConvention.Cdecl)]

(第一个方法没有任何问题的原因是它没有任何参数——__cdecl__stdcall 传递参数的方式不同,但它们都指定了整数return 值存储在 EAX 寄存器中。)