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 出错造成的,请高手指点迷津在线等,谢谢!
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 出错造成的,请高手指点迷津在线等,谢谢!
解决方案 »
- 入门问题:我在一个imgBtn里对一个TextBox.text赋值,在界面上看不到TextBox刷新。何故?
- socket如何在一个程序中实现收发文件的两种功能
- 我是初学者,请各位高手帮忙,,,,在线等,急..........
- 如何把服务端的pdf存到客户端
- 达人9我,关于jmail收信的乱码问题
- 新手求助。。。界面隐藏
- 小菜鸟求指点
- 【讨论】表中的ID列,用36位GUID好还是数字标示列好?
- 关于KindEditor上传图片错误问题
- C#叫号系统如何编写和调用webservic?
- c# 如何保存udpClient.Send(bytes, bytes.Length)发过来的数据?已发送成功
- 大量数据封装到类,然后保存在内存中,等待使用 怎么做?
public struct VOCLINK_PARAM
{
/// TCHAR[16]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] sVocIp; /// UINT->unsigned int
public uint nPort;
}string类型与byte类型转换string vocip = “192.168.4.44”;
byte[] bytevocip = new byte[16];
Encoding.Default.GetBytes(vocip).CopyTo(bytevocip, 0);
根据你的C++ DLL编译条件
若是使用了Unicode则TCHAR是WCHAR,双字节了
因此,一般不是使用CharSet.Auto,而是指定CharSet.ANSI或CharSet.Unicode
然后:
/// TCHAR[16]
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public String sVocIp;
1、我不知道在定义结构体时到底指定ANSI还是Unicode
2、传入一个IP,程序会报错,说是读取了不安全的地址
C++里的数据类型和C#里的有驱动,比如根据编译格式不同,有的占一个字节有的占两个字节