質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

7241閲覧

WindowsAPI系の関数はなぜAやWが末尾についてるんでしょうか?

KOTTON

総合スコア47

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/08/07 23:45

質問

<Windows.h>に含まれる関数で、例えば

GetModuleHandleAGetModuleHandleWなど、同じ機能なのにAやWが付いてるものがあります。
また、GetModuleHandleというものもあり、これに関しては定義を見てみると

cpp

1#ifdef UNICODE 2#define GetModuleHandle GetModuleHandleW 3#else 4#define GetModuleHandle GetModuleHandleA 5#endif // !UNICODE

のようになっています。

#ifdef UNICODE というのは、ファイル設定がunicodeかマルチバイト文字列かを判定してるっぽいですが、であればGetModuleHandleを使えばどちらか合うほうを自動で選択してくれるので一番いいということでしょうか?

もし間違ってましたら、
これらはどのように使い分ければいいのか教えてください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

文字列の符号化の方法が異なります。

  • ANSI互換文字列(cp932 いわゆるshift-jisなど)
  • Wide文字列

自動で選択してくれるので一番いい

場合によります。
末尾なしの関数を使う場合はマルチバイトかユニコードかがコンパイル時の設定により変わりますので
tchar等を用いて注意深くコーディングする必要がある割にうまみが少ないようにも感じます。

また末尾Aは楽なんですがtcharの場合と同様に「文字列のエンコードが想定通りなのか?」という問題に晒されます。

末尾WはUTF-16LEなので現在のところは最もエンコードを気にせずやれるかと思います。
\0が文字列中に入りこむ問題や、将来的にもUTF-16LEなのか?という問題はありますが

投稿2020/08/08 00:01

編集2020/08/08 00:17
asm

総合スコア15149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KOTTON

2020/08/08 00:04

なるほど、、ありがとうございます!
guest

0

ベストアンサー

かつては

  • Windows9x(基本的にA、一部Wも対応)
  • WindowsNT(AW両対応)
  • WindowsCE(Wのみ対応)

と同じWin32APIと言ってもOSにより使用可能なAPIが異なっていました。
AWなしで書いておけば同じソースコードで対応が可能でした。
今はWindowsNT系しかありませんが…
また、新規追加されるAPIではAWがつかずにUNICODE版しか無いこともあります。

GetModuleHandleを使えばどちらか合うほうを自動で選択してくれる

はい。
ただし、TCHAR_Tマクロを使用するなど正しく文字セットが切り替わるようにしておかないと、ビルドエラーの原因となります。
古いソースを流用するとかでなければ、マルチバイト文字セットの設定でビルドし直すことはないかもしれませんが…
プロジェクトの文字セット指定に関わらず、AWを指定して明示的に呼び出すことも可能です。

投稿2020/08/07 23:57

編集2020/08/08 00:10
SHOMI

総合スコア4079

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KOTTON

2020/08/08 00:05

どれも聞いたことないレベルの古いOSですね! なるほど 確かにマクロを使ったほうがよさげですね、ありがとうございます
guest

0

GetModuleHandleを使えばどちらか合うほうを自動で選択してくれるので一番いいということでしょうか?

自動という訳ではなく、プリプロセッサでUNICODEを定義すると、GetModuleHandleWが使用されます。ANSI文字列、ワイド文字列(Unicode)のどちらを使用するかという区別でAとWがついています。

VC2019の場合、プロジェクト設定の、構成プロパティ>詳細>文字セットでUnicode文字セットを使用するを選択すると、コンパイルオプションでUNICODEが定義されます。今のVC++は、デフォルト状態ではプロジェクト設定がUnicode使用になっています。

ANSI版のAPIは他言語(例えば中国語)のファイル名が扱えなかったりするので、多言語対応を意識するのであればUnicodeにした方がよいです。文字を扱わないプログラムなら、どちらでも特に問題無いと思われます。

Unicode 対応

投稿2020/08/08 00:13

編集2020/08/08 00:15
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

C

1HMODULE GetModuleHandleA(LPCSTR lpModuleName); // LPCSTR = const char* 2HMODULE GetModuleHandleW(LPCWSTR lpModuleName); // LPCWSTR = const wchar_t*

マルチバイト文字 と UNICODE の両方に対応すべくふたつの関数が用意されています。

C++(やC#,Java)なら関数のオーバロード「引数の数/型が異なれば同じ関数名でも別モノとして扱う」
ができるのですが、Cではそれができんので名前の異なる関数が用意されています。

それだと マルチバイト文字/UNICODE によってプログラマが
適宜呼び分けにゃならずメンドクセーので、
どちらの設定であっても同じコードに見せかけるべく、
#define GetModuleHandle ~ が提供されている、と。

投稿2020/08/08 00:05

episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KOTTON

2020/08/08 00:06

とても分かりやすい説明ありがとうございます 背景がわかりました C++ユーザーであれば GetModuleHandleを使えばよさげですね!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問