C/C++写的通过读取串口返回值的dll会闪退或提示尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
//打开时钟卡
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);提示尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
或者没有错误提示直接退出了,请问下是程序有什么问题吗 ?