c# - 发生 PinvokeStackImbalance。抛出了这个异常,但我不知道错误是什么?

标签 c# c++ pinvoke marshalling dllimport

异常(exception):

托管调试助手“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# 类

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++ 中是相同的?

最佳答案

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

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

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

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

关于c# - 发生 PinvokeStackImbalance。抛出了这个异常,但我不知道错误是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32449937/

相关文章:

c# - OxyPlot:使用 OxyPlot 和 WindowsForms 在一个窗口上绘制多个图形

php - 在 PHP 中运行 C++ 脚本

c# - 在 32 位和 64 位运行时编码(marshal)结构时的不同行为

c# - P/从 wlanapi.dll 调用 WlanHostedNetworkQueryStatus

c# - 在 Linux 中从 C# .net 核心控制台调用 C++ 共享库

c# - .NET 3.5 中的 URL 重写

C# Windows 窗体 : Drop a picture into a WPF RichTextBox (in ElementHost)

c# - 使用 Dapper 查询单个项目并转换为模型

c++ - 按类型特化模板类成员函数

c++ - 在 C++ 中初始化 const 字符串的静态 const 数组