C#中调用VC6.0++的dll关于数据封送的问题

Li_Huiyi 2010-10-07 10:19:29
最近在使用视频服务器的SDK开发,要调用一个动态链接库内的函数,有一个函数搞了2天了还没有过去,我只好再次来求助了...

//直接通过COM口收发数据
typedef struct tagJB_COM_DATA
{
DWORD dwSize;
DWORD dwChannel; //通道号
BOOL bIs485; //485 or 232
char DataBuf[]; //最大128
}JB_COM_DATA;

// 函数
DWORD WINAPI JBNV_SetServerConfig(HANDLE hServer,DWORD dwCmd,LPVOID lpData,DWORD dwSize);// 配置服务器参数

// 下面这个SDKDemo中对上面函数的调用:
DWORD SendPTZControlToServer(
BYTE *lpData, //要发送的COM数据,最多一次256个字节
int nSize //数据长度
)
{
BYTE bComData[280];
JB_COM_DATA *lpcomdata = (JB_COM_DATA *)bComData;
lpcomdata->dwSize = sizeof(int) * 3 + nSize;
lpcomdata->dwChannel = 0;
lpcomdata->bIs485 = TRUE;
memcpy(lpcomdata->DataBuf,lpData,nSize);
JBNV_SetServerConfig(m_hServer, //服务器句柄
CMD_SEND_COMDATA,lpcomdata,lpcomdata->dwSize);
return 0;
}


下面是我在C#中写的代码:

// 结构定义
/// <summary>
/// 直接通过COM口收发数据
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct JBNV_COMData
{
public uint dwSize;
public uint dwChannel;
public bool bIs485;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 9)]
public byte[] dataBuf; // 因为只需要传串口命令,我认为这样定义比较方便
// SizeConst为9是因为最长的串口命令是9个字节
}
// 函数声明
[DllImport("JBNVSDK.dll", EntryPoint = "JBNV_SetServerConfig", CharSet = CharSet.Ansi)]
public extern static JBNV_ErrorCode SetServerConfig(IntPtr hServer, JBNV_ParaCMD dwCmd, JBNV_COMData lpData, uint dwSize);

// 函数调用
JBNV_COMData comData = new JBNV_COMData();
comData.dwSize = 12 + 9;
comData.bIs485 = true;
comData.dwChannel = 0;
comData.dataBuf = new byte[9] {0xA0, 0x01, 0x00, 0x03, 0x17, 0x01, 0xFF, 0xFF, 0xE5};
int sz = Marshal.SizeOf(comData); // 这个是调试的时候用来看数据结构大小的
JBNV_ErrorCode re = JBNV_DLLFuction.SetServerConfig(hServer, JBNV_ParaCMD.CMD_SEND_COMDATA, comData, comData.dwSize);
if (re != JBNV_ErrorCode.JB_SUCCESS)
{
re = JBNV_DLLFuction.GetErrorMessage(re, ErrorMsg, 256u, 0x00000804);
MessageBox.Show(ErrorMsg.ToString());
}



在C#中调用的结果时出现异常:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

针对这个异常,我分别看了在VC中传入的数据结构的大小,即lpcomdata->dwSize就是21,而在C#中int sz = Marshal.SizeOf(comData)用这个看的这个结构的大小总是24...不晓得这多出的3个byte从哪里来的...我觉得这可能是这个异常的来源了。
到底该怎么定义这个结构变量char DataBuf[]?
我也试过用IntPtr传入结构的参数,和结构作为参数是一样的错误。

在线等答案!
...全文
148 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
Li_Huiyi 2010-10-08
  • 打赏
  • 举报
回复
to jointan
您的方法我都试过了,没有用。
JBNV_ErrorCode,JBNV_ParaCMD 在C#中的字义是两个枚举。
starts_2000 2010-10-08
  • 打赏
  • 举报
回复
// 结构定义
/// <summary>
/// 直接通过COM口收发数据
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct JBNV_COMData
{
public uint dwSize;
public uint dwChannel;
public bool bIs485;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 128)]
public byte[] dataBuf; // 因为只需要传串口命令,我认为这样定义比较方便
// SizeConst为9是因为最长的串口命令是9个字节
}
// 函数声明
[DllImport("JBNVSDK.dll", EntryPoint = "JBNV_SetServerConfig", CharSet = CharSet.Ansi)]
public extern static JBNV_ErrorCode SetServerConfig(IntPtr hServer, JBNV_ParaCMD dwCmd, ref JBNV_COMData lpData, uint dwSize);

// 函数调用
public void Test(byte []data)
{
JBNV_COMData comData = new JBNV_COMData();
comData.dwSize = (uint)(12 + data.Length);
comData.bIs485 = true;
comData.dwChannel = 0;

byte[] buffer = new byte[128];
Buffer.BlockCopy(data, 0, buffer, 0, data.Length);
comData.dataBuf = buffer;
JBNV_ErrorCode re = JBNV_DLLFuction.SetServerConfig(hServer, JBNV_ParaCMD.CMD_SEND_COMDATA, comData, comData.dwSize);
if (re != JBNV_ErrorCode.JB_SUCCESS)
{
re = JBNV_DLLFuction.GetErrorMessage(re, ErrorMsg, 256u, 0x00000804);
MessageBox.Show(ErrorMsg.ToString());
}
}
tommir3 2010-10-08
  • 打赏
  • 举报
回复


[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 9)]
public byte[] dataBuf;

//试试把上面这个改成下面这个试试
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]
public string dataBuf;

tommir3 2010-10-08
  • 打赏
  • 举报
回复
结构在内存中的存储是以4的整数倍进行存储,
你结构的大小应该是21,但给你分配的内存空间却是24,
所以sizeof(comData)的结果是24就是这个道理。
inttlegence 2010-10-08
  • 打赏
  • 举报
回复
先把返回值的枚举改成 System.UInt32 试试
jointan 2010-10-07
  • 打赏
  • 举报
回复
试试将bool改为Int32 ,直接把dataBuf放大到128,dwSize不要用SizeOf计算,设为用12加有效的dataBuf位数

JBNV_COMData lpData改为ref

另外:
JBNV_ErrorCode,JBNV_ParaCMD 在C#中的字义是两个枚举吗?

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧