C/C++写的通过读取串口返回值的dll会闪退或提示尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

wangzhe117 2017-09-25 11:40:21
//打开时钟卡
extern "C" _declspec(dllexport)
int _stdcall OpenUsbTimer(LPCTSTR Port)
{
//hCom =CreateFile("COM3", //COM1口
//GENERIC_READ|GENERIC_WRITE, //允许读和写
//0, //独占方式
//NULL,
//OPEN_EXISTING, //打开而不是创建
//FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重叠方式
//NULL);
//if(hCom ==INVALID_HANDLE_VALUE)
//{
////MessageBoxA("打开COM失败!");
//return 0;
//}
//return 1;

DCB dcb; // 串口通信设备控制参数结构体
BOOL bSuccess;
hCom =CreateFile(Port, //COM1口
GENERIC_READ|GENERIC_WRITE, //允许读和写
0, //独占方式
NULL,
OPEN_EXISTING, //打开而不是创建
0,//同步方式//FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重叠方式
NULL);
/*if(hCom ==INVALID_HANDLE_VALUE)*/
if(hCom==(HANDLE)-1)
{
MessageBoxA(NULL,"打开COM失败","USB时钟卡",0);
return 0;
}

bSuccess = GetCommState(hCom, &dcb);
if ( !bSuccess )
{
MessageBoxA(NULL,"打开COM失败","USB时钟卡",0);
return 0;
}
dcb.BaudRate = 9600;//波特率,默认9600
dcb.ByteSize = 8;//数据位,默认8
dcb.Parity = NOPARITY; //校验位,默认无
dcb.StopBits = 1;//停止位,默认1
bSuccess = SetCommState(hCom, &dcb);
if ( ! bSuccess )
{
MessageBoxA(NULL,"打开COM失败","USB时钟卡",0);
return 0;
}

SetupComm(hCom,100,100) ;
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 1000 ;
CommTimeOuts.ReadTotalTimeoutMultiplier = 1000 ;
CommTimeOuts.ReadTotalTimeoutConstant = 1000 ;//设定写超时
CommTimeOuts.WriteTotalTimeoutMultiplier = 1000 ;
CommTimeOuts.WriteTotalTimeoutConstant = 1000 ;
SetCommTimeouts(hCom, &CommTimeOuts ) ;//设置超时

//PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
return 1;
}

//关闭时钟卡
extern "C" _declspec(dllexport)
int _stdcall CloseUsbTimer()
{
/** 如果有串口被打开,关闭它 */
if( hCom != INVALID_HANDLE_VALUE )
{
CloseHandle( hCom );
hCom = INVALID_HANDLE_VALUE;
}
return 1;
}

//读取当前日期时间的数值
extern "C" _declspec(dllexport)
int _stdcall ReadCurrentTime(char *DateStr)
{
int iIndex = 0;
int flag = 1;
int li_ret = 0;
char DateBuf[128],TimeBuf[128];
char buf;
DWORD dwErrorFlags;
COMSTAT ComStat;
BOOL bWriteStat;
//if( hCom != INVALID_HANDLE_VALUE )
if(hCom!=(HANDLE)-1)
{
static char *data={"AT+QCLK"};
char lpOutBuffer[8]; //这个是要发送的数据
memset(lpOutBuffer,'\0',8);//前7 个字节先清零
lpOutBuffer[0]= 'A';//发送缓冲区的第1 个字节为DC1
lpOutBuffer[1]= 'T';//第2 个字节为字符0(30H)
lpOutBuffer[2]='+';//第3 个字节为字符0(30H)
lpOutBuffer[3]='Q';// 第4 个字节为字符1(31H)
lpOutBuffer[4]='C';//第5 个字节为字符0(30H)
lpOutBuffer[5]='L';//第6 个字节为字符1(31H)
lpOutBuffer[6]='K';//第7 个字节为字符ETX
DWORD dwBytesWritten=7;


COMSTAT ComStat;
DWORD dwErrorFlags;
BOOL bWriteStat;
ClearCommError(hCom,&dwErrorFlags,&ComStat);
PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXABORT);
bWriteStat=WriteFile(hCom,lpOutBuffer,dwBytesWritten, &dwBytesWritten,NULL);
if(!bWriteStat)
{
li_ret = 0;
}

if (dwBytesWritten != sizeof(lpOutBuffer))
{
li_ret = 0;
}

PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXABORT);
char str[128];
memset(str,'\0',128);
DWORD wCount=128;//读取的字节数
BOOL bReadStat;
bool abContinue = true;
bReadStat=ReadFile(hCom,str,sizeof(str),&wCount,NULL);
if(!bReadStat)
{
MessageBoxA(NULL,"读串口失败!","USB时钟卡",0);
li_ret = 0;
}

if(wCount>0 )
{

static char str1[] = "AT+QCLK\r\n";

char* target = str + strlen(str1) + 1;
target[strlen(target) - 1] = '\0';
unsigned int len = strlen(target);

string stryear="";
for (unsigned int i = 0; i<(len-1); i++)
{

target[i] = target[i] - i - 10;
if(i<4)
{
stryear=stryear+target[i];
}
if(i==4)
{
int num=atoi(stryear.c_str());
if(num>2000)
{
li_ret = 1;
}
}
}

strcpy(DateStr,target);


}

PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
}else
{
MessageBoxA(NULL,"3.取数失败...","USB时钟卡",0);
}

return li_ret;
}

在C#中调用

[DllImport("UsbTimer.dll")]
static extern int OpenUsbTimer(string Port);
[DllImport("UsbTimer.dll" ,CharSet = CharSet.Ansi,CallingConvention=CallingConvention.StdCall)]
static extern int ReadCurrentTime(StringBuilder DateStr);


private void button15_Click(object sender, EventArgs e)
{
int li_ret = OpenUsbTimer("COM3");
if (li_ret == 1)
{
timer1.Interval = 100;
timer1.Start();
}
else
{
CloseUsbTimer();
}

}

void timer1_Tick(object sender, EventArgs e)
{
try
{
StringBuilder ls_DateStr = new StringBuilder();

int li_ret;

li_ret = ReadCurrentTime(ls_DateStr);

if (li_ret == 1)
{
textBox_RealTime.Text = ls_DateStr.ToString();

}
else
{
textBox_RealTime.Text = "日期时间无效,请检查";
}

}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

//CloseUsbTimer();

}

程序会运行一段时间后
li_ret = ReadCurrentTime(ls_DateStr);提示尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
或者没有错误提示直接退出了,请问下是程序有什么问题吗 ?
...全文
586 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
metohang 2017-12-21
  • 打赏
  • 举报
回复
textBox_RealTime.Text = ls_DateStr.ToString(); 推荐用字符串拷贝吧。

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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