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 までのコンポートでも機能します)。問題は、私のコンポートが常に 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;
}

これはコンパイルされず、次のエラーが返されます: error 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' : 宣言されていない識別子が返されます

私はあまり専門家ではありませんが、しばらくの間これに取り組んできました。L"\\\\.\\COM20"ユーザーがcomportを指定でき、CreateFileが引き続き機能するように置き換える方法を誰かに教えてもらえますか? ありがとう!

4

6 に答える 6

11

とを使用std::wstringしてstd::wcinstd::wcout「ユニコード文字列」で直接入力を実行するか、Microsoft の変換関数を調べることができます。

最初のオプション (推奨) を使用する場合でも、関数を使用して値 (へのポインター)c_str() にアクセスする必要があります。LPCWSTRconst 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

私は最近これに遭遇しました。Unicodeはこのアプリケーションの範囲外であったため、Unicodeを無効にしました。

于 2010-09-24T03:41:53.860 に答える
0

追加の参考資料として、ATL 変換マクロ (例: CA2CW など) を参照してください。これらは (適切に使用すれば) ほとんどすべての単純な変換ケースをインラインで処理できます。

あなたの例では、 std::string を使用してから、次を使用できます。

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

ここでの文字列変換に関する一般的な情報: http://www.codeproject.com/KB/string/cppstringguide2.aspx

于 2010-09-24T06:56:17.657 に答える
0

(何らかの理由で) ANSI 文字列を使い続けることにした場合は、MultiByteToWideChar関数を調べてください。しかし、ANSI 文字列はほとんど時代遅れです。

于 2010-09-24T03:10:16.563 に答える