2
votes

I am getting a PInvokeStackImbalance: 'PInvokeStackImbalance was detected Message: A call to PInvoke function 'ConvertedClass::MapViewOfFile' 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.'

I am fairly new to DLL use, and just managed to work out a few tutorials today.

Any help would be appreciated.

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);

Edit: It was a bad argument.. The 5th arg should be UIntPtr instead of ulong. this is how i feel right now

2
"The 5th arg should be uint instead of ulong." No, it should be UIntPtr. Or you'll end up with the same problem when you switch to 64 bit process! - David Heffernan
Actually, I realised SIZE_T is unsigned so to be 100% accurate, UIntPtr is the way to go. - David Heffernan
By the way, you do know that .net 4 has added support for memory mapped files - David Heffernan
I found that in reading, and in all honesty, I would have liked to do the most cutting edge stuff but I was given some c++ and am pretty new to programming (fresh diploma) and decided to port over what I had been given, since most if it is still greek to me. (ported over with stacks help ofcourse) - kevp

2 Answers

2
votes

The final parameter is SIZE_T. That's unsigned, and 32 bits in a 32 bit process and 64 bits in a 64 bit process. So the best solution is to use UIntPtr for the final parameter.

I would use the following:

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

Your code uses ulong which is always 64 bits wide. And your process is a 32 bit process which explains why the P/invoke marshaller has detected a stack imbalance.

0
votes

The 5th parameter should be an uint, not ulong.

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

For P/Invoke, you can use sample code from pinvoke.net. http://www.pinvoke.net/default.aspx/kernel32.mapviewoffile