2

CHAR*2つを入力として受け取る関数があります。int _stdcall FileTrans(char* InFile, char* OutFile)DLLプロジェクトで。

関数では、いくつかのプロセスの後に呼び出しCopyFile(InFile, OutFile, false);ています(ファイルとは関係ありません)。しかし、それは両方の入力が必要であると言っていますLPCWSTR。私はそれをグーグルで検索しましたが、非常に興味深いものは見つかりませんでした。

4

1 に答える 1

7

文字列パラメータを受け入れるすべてのWindowsAPI関数と同様に、実際にはCopyFile関数には2つのバリエーションがあります。

  • CopyFileAはANSIバージョンであり、システムのデフォルトの文字セットで狭い(非Unicode)文字列を取ります。基本的に、タイプのパラメーターを受け入れますconst char*が、WindowsヘッダーはLPCSTRこれにtypedefを使用します。

  • CopyFileWは、Unicode文字列を使用するワイドバージョンです。これを行うために、タイプのパラメーターを受け入れますw_char*が、WindowsヘッダーはこれにtypedefLPCWSTRを使用します(typedefの追加に注意してくださいW)。

次に、UNICODEプリプロセッサマクロがプロジェクトに定義されているかどうか(Windowsヘッダーを含める前のコードで定義されているか、Visual Studioのプロジェクトのプロパティで定義されているか)に応じて、Windowsヘッダーは装飾されていないCopyFileをCopyFileAまたはCopyFileWとして定義します。当然、UNICODEが定義されている場合、CopyFileはUnicodeバージョンのCopyFileWとして定義されます。それ以外の場合は、CopyFileAとして定義されます。一般的なCopyFile関数の呼び出しは、コンパイル時に正しいバリアントに自動的に解決されるという考え方です。

もちろん、そのすべてを理解したので、ほとんど忘れることができます。最近のWindowsプログラミングでは、古いANSIバージョンの関数を呼び出したり、狭い文字列を処理したりする理由はまったくありません。char*文字列型としても使用できることを忘れてください。これらの文字列はあなたにとって死んでいます。これから使用する文字列は、文字で構成されるUnicode文字列のみですwchar_t。したがって、UNICODEシンボルは常にコードに対して定義する必要があり、WWindowsAPI関数のバージョンのみを使用する必要があります。

UNICODECopyFileW関数のプロトタイプ(定義済みでCopyFileを呼び出したときに得られるものと同じもの)をもう一度見ると、次のことがわかります。

BOOL WINAPI CopyFile(LPCWSTR lpExistingFileName,
                     LPCWSTR lpNewFileName,
                     BOOL bFailIfExists);

上記で学習したことを思い出してください。これは、ワイド文字で構成されるCスタイルの文字列であるLPCWSTRのtypedefの同義語です。関数がこれらの値を変更しないためconst wchar_t*、パラメータがマークされている理由はすでにご存知でしょう。const

また、これらがもう使用する必要がある唯一のタイプの文字列であることも上で学んだので、次のステップは、幅の広い文字列を受け入れるようにFileTrans関数を変更することです(const変更しない場合は作成します)。

int _stdcall FileTrans(const wchar_t* InFile, const wchar_t* OutFile);

これで、FileTransの内部から、適切なタイプの文字列があるため、問題なくCopyFileを呼び出すことができます。


ただし、少し無料で追加のアドバイスがあります。C++で生のCスタイルの文字列を使用しないでください。std名前空間で<string>ヘッダーによって定義されたC++文字列クラスを常に使用します。

このクラスには、2つの一般的なバリアントがありstd::stringますstd::wstring。以前と同様に、は幅のw広い文字列を指します。これは、Windowsで使用する唯一のタイプです。コードベース全体std::wstringの新しい代替品もそうです。CHAR*

FileTrans関数の宣言を次のように変更します。

#include <string>

// ...some other stuff...

int __stdcall FileTrans(const std::wstring& InFile, const std::wstring& OutFile);

元のパラメータをオブジェクトへのCHAR*定数参照に変更したことに注意してください。std::wstring関数内でこれらの値のいずれも変更しないため、ここでは定数参照が適切に機能します。

定数の意味、参照の使用方法、またはクラス型がC ++で一般的にどのように機能するかが不明な場合は、お気に入りのC ++ブックを参照してください)—これはすべてのC++プログラマーに必要な知識です。C ++はCと同じ言語ではないため、同じイディオムは適用されないことに注意してください。多くの場合、物事を行うためのより良い方法があり、これは確かにそのような場合の例です。

于 2013-03-17T07:36:33.707 に答える