C#调用C++写的Dll的问题,尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
仙剑 2012-01-17 03:49:47 DLL中有回调函数,还有结构体
DLL中结构体,回调函数和函数的原型如下:
typedef struct _VOCLINK_PARAM {
TCHAR sVocIp[16];
UINT nPort;
} VOCLINK_PARAM, *PVOCLINK_PARAM;
typedef struct _VMCCB_EVT {
UINT EvtCode;
UINT RetCode;
UINT Channel;
UINT uBufferLen; // pBuffer 's length
void* pBuffer; // Buffer for holding extra info
} VMCCB_EVT, *PVMCCB_EVT;
typedef void (*VLVMC_CB)( long VocHandle, const PVMCCB_EVT pVmcEvt, LPARAM lpData );
_DLLIMP long CALL_CONVENT
VLVmcOpen( const VLVMC_CB pVmcCB, LPARAM lpData, long *pVmcHandle );
_DLLIMP long CALL_CONVENT
VLVmcConnectVoc( long VmcHandle, const PVOCLINK_PARAM pVocSrv, long *pVocHandle );
C#中对应类型定义如下:
public static class VMCOperator
{
/// Return Type: int
///pVmcCB: VLVMC_CB
///lpData: LPARAM->LONG_PTR->int
///pVmcHandle: int*
[DllImportAttribute("VLVmc.dll", EntryPoint = "VLVmcOpen", CallingConvention = CallingConvention.StdCall)]
//public static extern int VLVmcOpen(VLVMC_CB pVmcCB, [MarshalAsAttribute(UnmanagedType.SysInt)] int lpData, ref int pVmcHandle);
public static extern int VLVmcOpen(VLVMC_CB pVmcCB, int lpData, ref int pVmcHandle);
/// Return Type: int
///VmcHandle: int
[DllImportAttribute("VLVmc.dll", EntryPoint = "VLVmcClose", CallingConvention = CallingConvention.StdCall)]
public static extern int VLVmcClose(int VmcHandle);
/// Return Type: int
///VmcHandle: int
///pVocSrv: PVOCLINK_PARAM->_VOCLINK_PARAM*
///pVocHandle: int*
[DllImportAttribute("VLVmc.dll", EntryPoint = "VLVmcConnectVoc", CallingConvention = CallingConvention.StdCall)]
public static extern int VLVmcConnectVoc(int VmcHandle, ref VOCLINK_PARAM pVocSrv, ref int pVocHandle);
/// Return Type: int
///VocHandle: int
[DllImportAttribute("VLVmc.dll", EntryPoint = "VLVmcDisconnectVoc", CallingConvention = CallingConvention.StdCall)]
public static extern int VLVmcDisconnectVoc(int VocHandle);
}
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
public struct VOCLINK_PARAM
{
/// TCHAR[16]
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
public string sVocIp;
//public char* sVocIp;
/// UINT->unsigned int
public uint nPort;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct VMCCB_EVT
{
/// UINT->unsigned int
public uint EvtCode;
/// UINT->unsigned int
public uint RetCode;
/// UINT->unsigned int
public uint Channel;
/// UINT->unsigned int
public uint uBufferLen;
/// void*
public IntPtr pBuffer;
}
/// Return Type: void
///VocHandle: int
///pVmcEvt: PVMCCB_EVT->_VMCCB_EVT*
///lpData: LPARAM->LONG_PTR->int
//[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void VLVMC_CB(int VocHandle, ref VMCCB_EVT pVmcEvt, int lpData);
调用函数的代码:
private void btnOpenVMC_Click(object sender, RoutedEventArgs e)
{
vmc_handler = 0;
int lpdata = 0;
if (VMCOperator.VLVmcOpen(vmc_cb, lpdata, ref vmc_handler) == VLVMC_ERR_SUCCESS)
{
MessageBox.Show("VMC Opened");
voc_link_param.sVocIp = "192.168.4.44";
voc_link_param.nPort = 3000;
voc_handler = 0;
if (VMCOperator.VLVmcConnectVoc(vmc_handler,ref voc_link_param, ref voc_handler) == VLVMC_ERR_SUCCESS)
{
MessageBox.Show("Voice Connected");
}
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
vmc_cb = new VLVMC_CB(OnVLVMC_CB);
voc_link_param = new VOCLINK_PARAM();
vmccb_evt = new VMCCB_EVT();
}
private void OnVLVMC_CB(int voc_handler, ref VMCCB_EVT vmccb_evt, int lpdata)
{
MessageBox.Show(vmccb_evt.EvtCode.ToString());
}
在调用VLVmcConnectVoc函数时就报错:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
看了网上有人加上了委托的属性 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
可是这样做虽然不报错了,但结果不对,不知道是不是封送 sVocIp 出错造成的,请高手指点迷津。。。在线等,谢谢!