-
September 19th, 2013, 12:30 PM
#1
How to resolve a PInvokeStackImbalance was detected issue
I have started converting a C SDK to C# and have encountered a PInvokeStackImbalance was detected error that I just can't figure out how to resolve.
The details of the message is as follows:
PInvokeStackImbalance was detected
Message: A call to PInvoke function 'PInvoke!PlatformInvokeTest::CLIENT_Logout' 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.
Some info from the C SDK header file follows:
Code:
#ifndef LLONG
#ifdef WIN32
#define LLONG LONG
#else //WIN64
#define LLONG INT64
#endif
#endif
#ifndef CLIENT_API
#define CLIENT_API __declspec(dllexport)
#endif
#else
#ifndef CLIENT_API
#define CLIENT_API __declspec(dllimport)
#endif
#endif
#define CALLBACK __stdcall
#define CALL_METHOD __stdcall //__cdecl
// Register to the device
CLIENT_API LLONG CALL_METHOD CLIENT_Login(char *pchDVRIP, WORD wDVRPort, char *pchUserName, char *pchPassword, LPNET_DEVICEINFO lpDeviceInfo, int *error = 0);
// Log out the device
CLIENT_API BOOL CALL_METHOD CLIENT_Logout(LLONG lLoginID);
and finally my source code...
Code:
using System;
using System.Runtime.InteropServices;
class PlatformInvokeTest
{
static public long lLogin;
public delegate void fDisConnect(long lLoginID, IntPtr pchDVRIP, long nDVRPort, uint dwUser);
public delegate void fHaveReConnect(long lLoginID, IntPtr pchDVRIP, long nDVRPort, uint dwUser);
// [DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.StdCall)]
[DllImport("dhnetsdk.dll")]
public static extern bool CLIENT_Init(fDisConnect cbDisConnect, uint dwUser);
// [DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.StdCall)]
[DllImport("dhnetsdk.dll")]
public static extern void CLIENT_SetAutoReconnect(fHaveReConnect cbHaveReconnt, uint dwUser);
// [DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.StdCall)]
[DllImport("dhnetsdk.dll")]
public static extern long CLIENT_Login(string pchDVRIP, ushort wDVRPort, string pchUserName, string pchPassword, NET_DEVICEINFO lpDeviceInfo, IntPtr error);
// [DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.StdCall)]
[DllImport("dhnetsdk.dll")]
public static extern bool CLIENT_Logout(long lID);
// [DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.StdCall)]
[DllImport("dhnetsdk.dll")]
public static extern void CLIENT_Cleanup();
static int[] long2doubleInt(long a)
{
int a1 = (int)(a & uint.MaxValue);
int a2 = (int)(a >> 32);
return new int[] { a1, a2 };
}
public static void fDisConnectMethod(long lLoginID, IntPtr pchDVRIP, long nDVRPort, uint dwUser)
{
System.Console.WriteLine("Disconnect");
return;
}
public static void fHaveReConnectMethod(long lLoginID, IntPtr pchDVRIP, long nDVRPort, uint dwUser)
{
System.Console.WriteLine("Reconnect success");
return;
}
[StructLayout(LayoutKind.Sequential)]
public class NET_DEVICEINFO
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public byte[] sSerialNumber;
public byte byAlarmInPortNum;
public byte byAlarmOutPortNum;
public byte byDiskNum;
public byte byDVRType;
public byte byChanNum;
}
public static void Main()
{
fDisConnect fDisConnecthandler = fDisConnectMethod;
fHaveReConnect fHaveReConnecthandler = fHaveReConnectMethod;
NET_DEVICEINFO deviceinfo = new NET_DEVICEINFO();
IntPtr iRet = new IntPtr(0);
CLIENT_Init(fDisConnectMethod, 0);
CLIENT_SetAutoReconnect(fHaveReConnecthandler, 0);
lLogin = CLIENT_Login("192.168.1.198", 3112, "userid", "password", deviceinfo, iRet);
int[] al = long2doubleInt(lLogin);
if (al[0] <= 0)
Console.WriteLine("Login device failed");
else
{
Console.WriteLine("Login device successful");
CLIENT_Logout(lLogin);
CLIENT_Cleanup();
}
}
}
The error is thrown at the CLIENT_Logout method. Any assistance would be greatly appreciated.
Last edited by BobS0327; September 19th, 2013 at 01:10 PM.
-
September 22nd, 2013, 01:48 AM
#2
Re: How to resolve a PInvokeStackImbalance was detected issue
Is iRet returning an error?
-
September 22nd, 2013, 06:58 AM
#3
Re: How to resolve a PInvokeStackImbalance was detected issue
Single stepping thru the code and using the variable watch window indicates that iRet is always zero. But as the documentation below indicates, as long as the function returns successfully, iRet would be meaningless.
Calling CLIENT_Login always returns a good device id to me since I can use it to access the remote device. Thus, as the documentation indicates, iRet would be meaningless for me.
CLIENT_Login
registered user to device, when device terminal set user to multi-use(default user i.e. admin, not multi-use), so the account can register multiple times on device.
LLONG CLIENT_Login(
char *pchDVRIP,
WORD wDVRPort,
char *pchUserName,
char *pchPassword,
LPNET_DEVICEINFO lpDeviceInfo,
int *error = 0
);
Parameters
[in]pchDVRIP
device IP
[in]wDVRPort
device port
[in]pchUserName
username
[in]pchPassword
user password
[out]lpDeviceInfo
device info, as output parameter
[out]error
(when function returns successfully, its value is meanless),return to login wrong code,as follows:
wrong code meaning
1 wrong password
2 username not exist
3 login overtime
4 account already login
5 accoung locked
6 account on blacklist
7 insufficient resource,system busy
8 sub-connection failed
9 main connection failed
10 exceed max user connections
Return Values
failed return to 0,successful return to device ID,after successfully login operation on device may correspond to designated device via this value (device handle).
Remarks
after initialization may call the interface to register designated devices, if successful, device handle will be returned for call of related function.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|