4

使用 Windows CreateFile 函数寻址串行端口时,我似乎遇到了一些 TEXT / UNICODE 问题。有人可以帮忙指出我的错误吗?

我正在使用 VS 2008 在 VC++ 中编写一个 Win32 控制台应用程序。

我可以像这样创建一个句柄来寻址串行端口:

#include <iostream>    
#include <windows.h>
#include <string>

int main()
{

   HANDLE hSerial;

   hSerial = CreateFile( L"\\\\.\\COM20",
                         GENERIC_READ | GENERIC_WRITE,
                         0,
                         0,
                         OPEN_EXISTING,
                         FILE_ATTRIBUTE_NORMAL,
                         0);`

   return 0;
}

这工作得很好(该\\\\.\\位对于大于 COM9 的端口是必需的,并且也适用于那些高达 COM9 的端口)。问题是我的comport 并不总是COM20,所以我想让用户指定它是什么。

以下是我尝试过的一些事情:

#include <iostream>    
#include <windows.h>
#include <string>

int main()
{
   std::string comNum;
   std::cout << "\n\nEnter the port (ex: COM20): ";
   std::cin >> comNum;
   std::string comPrefix = "\\\\.\\";
   std::string comID = comPrefix+comNum;

   HANDLE hSerial;

   hSerial = CreateFile( comID,
                         GENERIC_READ | GENERIC_WRITE,
                         0,
                         0,
                         OPEN_EXISTING,
                         FILE_ATTRIBUTE_NORMAL,
                         0);`

   return 0;
}

这不会编译并返回错误:错误 C2664: 'CreateFileW' : cannot convert parameter 1 from 'std::string' to 'LPCWSTR'

我想也许当时指定 CreateFileA 会起作用,但这给出了基本相同的错误。

我也试过:

/*
everything else the same
*/   

hSerial = CreateFile( TEXT(comID),
                      GENERIC_READ | GENERIC_WRITE,
                      0,
                      0,
                      OPEN_EXISTING,
                      FILE_ATTRIBUTE_NORMAL,
                      0);`

它也不会编译并返回:错误 C2065: 'LcomID' : undeclared identifier

我不是专家,但我已经为此工作了一段时间。有人可以告诉我如何以L"\\\\.\\COM20"用户可以指定 comport 的方式进行替换,这样 CreateFile 仍然可以工作吗?谢谢!

4

6 回答 6

11

您可以使用std::wstringand直接在“unicode 字符串”std::wcinstd::wcout执行输入,也可以查看 Microsoft 的转换函数

如果您选择第一个选项(推荐),您仍然需要使用该c_str() 函数来访问一个LPCWSTR值(指向 的指针const wchar_t)。

示例解决方案(也不使用CreateFileW语法,以防止UNICODE宏出现问题):

#include <iostream>    
#include <windows.h>
#include <string>

int main()
{
   std::wstring comNum;
   std::wcout << L"\n\nEnter the port (ex: COM20): ";
   std::wcin >> comNum;
   std::wstring comPrefix = L"\\\\.\\";
   std::wstring comID = comPrefix+comNum;

   HANDLE hSerial;

   hSerial = CreateFileW( comID.c_str(),
                     GENERIC_READ | GENERIC_WRITE,
                     0,
                     0,
                     OPEN_EXISTING,
                     FILE_ATTRIBUTE_NORMAL,
                     0);`

   return 0;
}
于 2010-09-24T02:38:13.050 回答
2

如果您想继续使用,则在调用 时std::string使用其方法,例如:c_str()CreateFileA()

hSerial = CreateFileA( comID.c_str(), ...);
于 2010-09-24T06:11:50.943 回答
0

作为附加参考,请查看 ATL 转换宏(例如:CA2CW 等)。这些(如果使用得当)可以处理几乎所有简单的内联转换案例,而无需大惊小怪。

在您的示例中,您可以使用 std::string,然后使用:

CreateFile( CA2CT( comID.c_str() ), ... );
于 2010-09-24T02:47:09.707 回答
0

如果(出于某种原因)您决定继续使用 ANSI 字符串,请查看该MultiByteToWideChar函数。但是 ANSI 字符串已经过时了。

于 2010-09-24T03:10:16.563 回答
0

我最近遇到了这个。我只是禁用了 Unicode,因为 Unicode 完全超出了此应用程序的范围。

于 2010-09-24T03:41:53.860 回答
0

此处有关字符串转换的一般信息:http: //www.codeproject.com/KB/string/cppstringguide2.aspx

于 2010-09-24T06:56:17.657 回答