- ベストアンサー
GetProcAddressとUnicode、Ansiについて
先日似たような部分で疑問が生じましたが GetProcAddressについて、実践的な部分をもうちょっと詳しく知りたくなりました。 Unicode版、Ansi版での、ロードする関数名が 末尾にWかAがついてることが多いと思うのですが GetProcAddressには文字列を指定しなければならないため なるべく手間を避けるとしても #ifdef _UNICODE #define _FWA(x) #x"W" #define _tfuncwa(x) L#x L"W" #else #define _FWA(x) #x"A" #define _tfuncwa(x) #x"A" #endif こういう風にプリプロセッサに対してなんらかの配慮をして置いたうえで HMODULE hDLL( LoadLibrary(_T("Shlwapi.dll")) ); typedef HRESULT (__stdcall *Func)( LPCTSTR ); Func func = (Func)GetProcAddress(hDLL,_FWA(PathFileExists)); とかやるようにするか、若しくはDllから動的に引っ張ってくる関数の周りで使う文字列は UnicodeかAnsiかに決め打ちして、必要が生じるなら変換、といった配慮のいずれかは必ず必要になるのでしょうか?
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
以下の2種類の方法を検討しているのでしょうか? 1.ANSI文字列を受け取る関数とUnicode文字列を受け取る関数の両方をDLLに実装し、マクロで関数名を変換する 2.関数呼び出しの前後で、文字列の型が合わない場合は文字列変換処理を入れる Cの場合は上記のような方法で変換を行うことになると思います。 C++の場合、オーバーロード機能によって同じ関数名でも引数の型を別々のものにすることで、上記のような変換を行う必要はなくなるかと思います。 で、GetProcAddress関数ですが、この関数はちょっと特殊で、文字列の引数があるにもかかわらずANSI文字列を受け取る関数形式しかありません。(後ろにAとかWが付かない) なので、定数で書く場合は_Tマクロなど、Unicode定義は必要ありません。 また、変数で渡す場合はchar型で渡す必要があるため、wchar_t型になっている場合はあらかじめ文字列をchar型に変換しておく必要があります。
その他の回答 (1)
- gentoo314
- ベストアンサー率41% (15/36)
回答にはなっていませんが、DLLの遅延ロード機能を使用するとその辺の事は意識しなくて済むと思います。
お礼
ありがとうとございます♪ 遅延ロード機能というのは、具体的にはどうやって実現するもののことなのでしょうか?
補足
(事後) ある程度の見当はついたかも、という感じなので、時間ができたらじっくり調べてみることにします。
お礼
ありがとうございます。 自分でC++で作るとか、C++で作られたライブラリなら、しっかりしたやつならだいたい両方対応している可能性が高いはずなのでその手でおkだと思いますが WindowsAPIとかをこういう風に呼び出すなら、やはりこうするのがいいのでしょうかね? GetProcAddressそのものにはANSIしかない、ということは大丈夫です。これを使うのはおそらく手打ちですからね。 これに渡す文字が_Tで囲まれてると、マルチバイトでしかコンパイルできなくなるはずですねw 実際には上記マクロはこの場合 #ifdef _UNICODE #define _FWA(x) #x"W" #else #define _FWA(x) #x"A" #endif だけあれば十分かと思います。 _tfuncwa(x) は、出力してマクロが正常に機能するかチェックしたときに作った、おまけですw、 上記コードの場合なら 呼び出すことになる PathFileExistsA か PathFileExistsW に対しては、設定によってどちらでも対応できるように TCHARを使っておけばいい、ということになるはずです。 やはり よほどのことがない限り、そういうことなら文字列変換はわざわざやらないようにする方が良いですよね?