1. 程式人生 > >使用CreateFile函式開啟COM10及以上序列口

使用CreateFile函式開啟COM10及以上序列口

程式除錯時發現,使用CreateFile()開啟COM4時正常,開啟COM10時卻總是失敗。這兩個埠均為虛擬COM口,通過藍芽模擬串列埠完成資料收發,除了命名不同外,本質上並無任何不同。

而MSDN上對使用CreateFile()開啟裝置函式卻失敗返回並無詳細解釋,百思不得其解。上網百度一下找到了相關資料,原來是:

 

Win32 API函式CreateFile()除了可開啟普通檔案外,還可以開啟裝置,比如可用於開啟串列埠,獲得串列埠控制代碼。

使用CreateFile()函式開啟串列埠時檔案共享模式應設定為0(表示獨佔),建立引數設定為OPEN_EXISTING,模板必須設定為NULL。

如果為COM1至COM9,可使用“COM1”-“COM9”作為檔名傳遞給CreateFile()函式,函式可成功返回。但是,如果操作物件為COM10及以上的埠,以此方式命名檔名呼叫CreateFile()函式會返回INVALID_HANDLE_VALUE,表示埠無法開啟。

產生這種奇怪現象的原因是:微軟預定義的標準裝置中含有“COM1”-“COM9”。所以,“COM1”-“COM9”作為檔名傳遞給函式時作業系統會自動地將之解析為相應的裝置。但對於COM10及以上的串列埠,“COM10”之類的檔案名系統只視之為一般意義上的檔案,而非序列裝置。

為了增加對COM10及以上串列埠的支援,微軟規定,如果要訪問這樣的裝置,應使用這樣的檔名(以COM10為例):\\.

COM10

所以,對於COM10及以上的串列埠,CreateFile()的呼叫樣式應調整如下:

CreateFile(

"\\\\.\\COM10",           // 定義串列埠名

fdwAccess,                // 存取模式(讀寫)

0,                               // 共享模式:必須設定為0,表示裝置獨佔使用

NULL,                        // 保密性

OPEN_EXISTING,      // 必須設定為OPEN_EXISTING

0,                               // 檔案屬性,如果是非同步模式,可設定為

NULL                         // 模版,串列埠裝置必須設定為NULL

);

 

需要注意的是:這套命名規範同樣適用於COM1-COM9。

參考處:http://support.microsoft.com/?id=115831

 

另,MSCOMM串列埠控制元件無此問。估計是其底層程式注意到了此問題並妥善地解決了。