首页 > 解决方案 > WPFApp 中的 DLLImport 不起作用(PInvokeStackImbalance)

问题描述

我创建了两个 C# 应用程序,一个是 WPF 应用程序,另一个是控制台应用程序。两者都有相同的代码(我创建了控制台应用程序来测试 C# 代码并复制到真正的应用程序中,即 WPF 应用程序)。

我正在使用的 DLLImport 如下所示:

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateFileA(string lpFileName, long dwDesiredAccess, uint dwShareMode, uint lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);

并在这样的代码中调用:

 Process process = Process.GetCurrentProcess();
 ModuleInformation mi = new ModuleInformation();
 IntPtr dllModule = GetModuleHandleA(dllName);

 GetModuleInformation(process.Handle, dllModule, out mi, (uint)(IntPtr.Size * 3));
 IntPtr baseAddress = mi.lpBaseOfDll;
 IntPtr dllFile = CreateFileA(dllPath, 0x80000000L, 1, 0, 3, 0, (IntPtr)0);

在控制台应用程序中,代码运行良好,但在 WPF 应用程序中,我收到以下错误:

托管调试助手“PInvokeStackImbalance”:“对 PInvoke 函数“WpfApp1!WpfApp1.Class1::CreateFileA”的调用使堆栈不平衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。

我试图改变调用约定,但错误没有改变。为什么它在控制台应用程序中有效,但在 WPF 应用程序中无效?

编辑:现在 VirtualProtect 发生同样的错误:

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, long flNewProtect, out IntPtr lpflOldProtect);

标签: c#wpf

解决方案


尝试使用pinvoke.net的确切声明:

[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern IntPtr CreateFileA(
    [MarshalAs(UnmanagedType.LPStr)] string filename,
    [MarshalAs(UnmanagedType.U4)] FileAccess access,
    [MarshalAs(UnmanagedType.U4)] FileShare share,
    IntPtr securityAttributes,
    [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
    [MarshalAs(UnmanagedType.U4)] FileAttributes flagsAndAttributes,
    IntPtr templateFile);

推荐阅读