以下のurlをcのコマンドラインでコンパイルしましたが、エラーがでます。x86でコンパイルしています。windows 10 64bitです。
http://www.winsock2.org/samples/Ch05/PingI/pingi.c
HANDLE hndlIcmp; // ICMP.DLLへのLoadLibrary()ハンドル
hndlIcmp = LoadLibrary("ICMP.DLL");
if (hndlIcmp == NULL)
{
fprintf(stderr, "\nCould not load ICMP.DLL\n");
return;
}
// ICMP関数ポインタを取得
pIcmpCreateFile = (HANDLE(WINAPI *)(void))
GetProcAddress(hndlIcmp, "IcmpCreateFile");<=hndlIcmpで"HANDLE"の引数は型"HMODULE"のパラメーターと互換性がありません。
なぜ、このエラーがでるのかわかりません。
教えてください。
HANDLEではなくHMODULEで宣言してください
https://msdn.microsoft.com/ja-jp/library/cc429133.aspx
windows.hかwindef.hだったかに定義があったと思いますが
そのサイトは結構古いので
そのプログラム作成当時は互換性のある型だったのかも
解決法としてはdeguchoさんが書かれているとおりhndlIcmpの変数宣言をHANDLEからHMODULEに変更することがあげられます。
で、質問内容の「なぜエラーが表示されるか」ですが、WinAPIのかなり古い時代(私が知っている範囲ではVisualStudio6とかその付近までさかのぼる)ではWinAPIでハンドルとして定義されている変数型は名前の付け方が違うだけで実は同じ型だった、という時代があります。
この場合のハンドルは基本的にvoid *の別名と思っていただければいいです。つまり型宣言としては
typedef void * HANDLE;
typedef void * HMODULE;
typedef void * HWND;
typedef void * HDC;
…
にかなり近いことが書かれていたためHMODULE型の変数を受け取るはずのGetProcAddressがHANDLE型の変数を引数として渡されても問題なく通ってしまう、ということがあったわけです。この場合では上記サイトのサンプルコードならエラーは出ないわけですね。
今ではハンドルの型が異なる場合はコンパイルエラーが出るようにヘッダーでは宣言されています。(ただし、結局はこの場合のハンドルはすべて「何かへのメモリ」という共通の意味があり、変数のサイズとしてはvoid *と同じですが)
なお、昔の定義のされ方であっても
#define STRICT
をwindows.hのインクルードの前に記述しておけばHANDLE型とHMODULE型は別の型の扱いになるようになってはいたと記憶しておりますが…
ありがとうございます。
ありがとうございます。
2016/10/27 23:02:47