PInvoke c ++ dll使堆栈不平衡

时间:2019-03-14 09:32:22

标签: c# c++ vb.net pinvoke

我如何在vb.net项目中使用C ++ dll?

我具有要从vb.net调用的c ++ dll函数:

typedef void(CALLBACK *fRemoteConfigCallback)(DWORD dwType, void* lpBuffer, DWORD dwBufLen, void* pUserData);
NET_DVR_API LONG __stdcall NET_DVR_StartRemoteConfig(LONG lUserID, DWORD dwCommand, LPVOID lpInBuffer, DWORD dwInBufferLen, fRemoteConfigCallback cbStateCallback, LPVOID pUserData);
NET_DVR_API LONG __stdcall NET_DVR_GetNextRemoteConfig(LONG lHandle, void* lpOutBuff, DWORD dwOutBuffSize);

这是我在C#包装程序上编写的用于调用PInvoke的代码:

public delegate void fRemoteConfigCallback(uint lCommand, IntPtr lpBuffer, uint dwBufLen, IntPtr pUserData);
[DllImport("HCNetSDK.dll", CallingConvention = CallingConvention.StdCall)]
public static extern long NET_DVR_StartRemoteConfig(long lUserID, uint dwCommand, IntPtr lpInBuffer, uint dwInBufferLen, fRemoteConfigCallback cbStateCallback, IntPtr pUserData);
[DllImport("HCNetSDK.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int NET_DVR_GetNextRemoteConfig(long lHandle, IntPtr lpOutBuff, uint dwOutBuffSize);

然后我用以下代码调用包装器:

Dim m_struAttendanceRecordCfg As NET_DVR_ATTENDANCE_RECORD_CFG = New NET_DVR_ATTENDANCE_RECORD_CFG()
a = Marshal.AllocHGlobal(Marshal.SizeOf(m_struAttendanceRecordCfg))
'error on this line
iret = NET_DVR_GetNextRemoteConfig(mHandle, a, Marshal.SizeOf(m_struAttendanceRecordCfg))
Marshal.StructureToPtr(m_struAttendanceRecordCfg, a, False)
Marshal.FreeHGlobal(a)

基于我在Google上搜索的内容,这是因为变量的某些数据类型与C ++ dll不匹配?我应该更改什么才能使此代码起作用? 预先感谢。

编辑: 这是我编辑过的c#包装器:

[DllImport("HCNetSDK.dll")]
public static extern int NET_DVR_StartRemoteConfig(int lUserID, uint dwCommand, IntPtr lpInBuffer, uint dwInBufferLen, fRemoteConfigCallback cbStateCallback, IntPtr pUserData);
[DllImport("HCNetSDK.dll")]
public static extern int NET_DVR_GetNextRemoteConfig(int lHandle, IntPtr lpOutBuff, uint dwOutBuffSize);

vb.net代码

Dim m_struSearchInfoCond As NET_DVR_SEARCH_INFO_COND = New NET_DVR_SEARCH_INFO_COND()
Dim m_struAttendanceRecordCfg As NET_DVR_ATTENDANCE_RECORD_CFG = New NET_DVR_ATTENDANCE_RECORD_CFG()

Dim a As IntPtr
a = Marshal.AllocHGlobal(Marshal.SizeOf(m_struSearchInfoCond))
Dim sizeOfA As UInt16 = Marshal.SizeOf(a)
'if i change mHandle as Uint32, it throw error Overflow
Dim mHandle As Long = NET_DVR_StartRemoteConfig(lUser, NET_DVR_GET_ATTENDANCE_RECORD_INFO,a, sizeOfA, Nothing, Nothing)
If mHandle < 0 Then
   sizeOfA = NET_DVR_GetLastError()
End If
Marshal.StructureToPtr(m_struSearchInfoCond, a, False)
Marshal.FreeHGlobal(a)

Dim iret As Long = 0
While mHandle >= 0
    a = Marshal.AllocHGlobal(Marshal.SizeOf(m_struAttendanceRecordCfg))
    'if i change mHandle to long and pass it to this API (NET_DVR_GetNextRemoteConfig), it throw error "has unbalanced stack"
    lUser = NET_DVR_GetNextRemoteConfig(mHandle, a, Marshal.SizeOf(m_struAttendanceRecordCfg))
    Marshal.StructureToPtr(m_struAttendanceRecordCfg, a, False)
    Marshal.FreeHGlobal(a)
    fid = m_struAttendanceRecordCfg.dwEmployeeNo
End While

0 个答案:

没有答案