上一回我發表第一版本的串口類庫,收到了不少來信 ,提了不少意見和問題。我前一段時間又對這段代碼作了修正,改動較大,主要思路沒變,但更加規范並修改了幾個錯誤。這次代碼是完全按WIN32命名規范,適合用於VC++的開發,以前我一直用SDK,,用C風格的命名方式,將代碼與VC程序整合看起來有點別扭,這次就不會了。
幾個變動
一個缺陷,前一段時間我在2000下用8串口卡發現第10個串口打不開,查了MSDN找到了原因,這裡我做了修正。在NT/2000下 原來的代碼打開編號10以上端口用 :CreateFile(
將提示錯誤,這樣就OK:
"COM10",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //重疊I/O
NULL
);CreateFile(
將阻塞與非阻塞的方式的代碼作了整合,並可以選擇是否開啟監視線程:
"\\\\.\\COM10",//對應的就是\\.\COM10
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //重疊I/O
NULL
);
cnComm MyComm1(false, 0);// 第1個參數為是否啟動監視線程(這裡不用線程),
這樣讀寫代碼就不會像原來那樣重復;修正一個錯誤,原來我在關閉線程時用一下代碼退出 WaitCommEvent 的等待:
//第2個參數為阻塞(0)/異步方式(默認)
cnComm MyComm2;//默認啟動監視線程, 異步
cnComm MyComm3(true);//監視線程, 阻塞
::SetCommMask(_hCommHandle, 0);
::ResetEvent(_WaitOverlapped.hEvent);//這裡有筆誤,由於這兩句的得作用
//是一樣(雙保險退出WaitCommEvent),測試時沒發現
修正為
::SetEvent(_WaitOverlapped.hEvent);
還有一些小的地方就不說了。
一個較完整的范例:
#pragma warning(disable: 4530)
#pragma warning(disable: 4786)
#include "iostream"
#include "exception"
using namespace std;
#include "cnComm.h"
class MyComm : public cnComm
{
public:
virtual void OnReceive()
{
char Buffer[256];
if(Read(Buffer, 256))
cout << "Receive Data Form " <<
_dwPort << " : " << Buffer << endl;
}
};
int main(int argc, char *argv[])
{
try
{
//將COM1 COM2相連測試
cnComm Com1(false, 0);//阻塞
MyComm Com2;//繼承擴展使用 非阻塞
Com1.Open(1, 1200);
Com2.Open(2, 1200);
char Buffer[] = "test com";
Com1.Write(Buffer);
Sleep(300);
Com1.Close();
}
catch(exception &e)
{
cout << e.what() << endl;
}
return 0;
}
這個版本相信足夠用的, 我單位的在用串口加起來有四五十個,都沒問題,還有問題歡迎來信批評指教。
本文配套源碼