C#中的DLLImport调用不正确

时间:2012-05-22 20:37:22

标签: c# .net dll pinvoke

我得到了一个PInvokeStackImbalance:'检测到PInvokeStackImbalance 消息:对PInvoke函数'ConvertedClass :: MapViewOfFile'的调用使堆栈失衡。这很可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。'

我对DLL的使用相当新,并且今天设法编写了一些教程。

任何帮助都将不胜感激。

using System.Runtime.InteropServices;     

//dll
[DllImport("kernel32", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto)]

public static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, FileMapAccessRights dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, ulong dwNumberOfBytesToMap;)

string szSharedMemory = "FUNKY_BUSINESS";

//other dll call is successful and returns value
IntPtr hMem = OpenFileMapping(FileMapAccessRights.Write, FALSE, szSharedMemory);

///BOOM.. not this one
IntPtr pvHead = MapViewOfFile(hMem, FileMapAccessRights.Write, 0, 0, 0);

编辑:这是一个不好的论点..第五个arg应该是UIntPtr而不是ulong。 this is how i feel right now

2 个答案:

答案 0 :(得分:2)

最后一个参数是SIZE_T。那是无符号的,在32位进程中是32位,在64位进程中是64位。因此,最好的解决方案是使用UIntPtr作为最终参数。

我会使用以下内容:

[DllImport("kernel32")]
public static extern IntPtr MapViewOfFile(
    IntPtr hFileMappingObject,
    FileMapAccessRights dwDesiredAccess, 
    uint dwFileOffsetHigh, 
    uint dwFileOffsetLow, 
    UIntPtr dwNumberOfBytesToMap
);

您的代码使用的ulong总是64位宽。并且您的进程是一个32位进程,它解释了为什么P / invoke marshaller检测到堆栈不平衡。

答案 1 :(得分:0)

第五个参数应该是一个uint,而不是ulong。

public static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, FileMapAccessRights dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap;)

对于P / Invoke,您可以使用pinvoke.net中的示例代码。 http://www.pinvoke.net/default.aspx/kernel32.mapviewoffile