对PInvoke函数的调用在调试模式下使堆栈不平衡

时间:2015-03-09 19:37:05

标签: c# interop pinvoke dllimport

我最近开始研究涉及C#和本机代码之间通信的项目,因此我试图了解它是如何工作的。我已经从msdn加载了一个样本,尝试启动它,我发现它在Release模式下运行并在调试模式下崩溃。有人知道为什么吗?

// PInvokeTest.cs
using System;
using System.Runtime.InteropServices;

class PlatformInvokeTest
{
    [DllImport("msvcrt.dll")]
    public static extern int puts(string c);
    [DllImport("msvcrt.dll")]
    internal static extern int _flushall();

    public static void Main() 
    {
        puts("Test");
        _flushall();
    }
}

错误:

Additional information: A call to PInvoke function 'ConsoleApplication6!PlatformInvokeTest::puts' 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.

此代码来自以下网站:https://msdn.microsoft.com/en-us/library/aa288468(v=vs.71).aspx

1 个答案:

答案 0 :(得分:1)

引用this well detailed answer

  

当数据结构用于跟踪时,会发生堆栈不平衡   被调用的函数,参数和返回值被破坏或   错位的。

     

大多数情况下,堆栈是存储地址的内存指针   当前函数调用退出时控件将恢复的位置   呼叫者,召集者。这有不同的变体,有时是   函数的参数也附加到堆栈,以及   回报价值。这里最重要的是呼叫者和呼叫者   被调用者应该就如何将其恢复到先前状态达成一致   当被叫者退出时该协议通常被称为   召集公约。

您忘了指定calling convention

class PlatformInvokeTest
{
    [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int puts(string c);
    [DllImport("msvcrt.dll")]
    internal static extern int _flushall();

    public static void Main()
    {
        puts("Test");
        _flushall();
    }
}

Read more about x86 calling conventions