Visual studio 2015でPingプログラムを試しています。

以下の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"のパラメーターと互換性がありません。

なぜ、このエラーがでるのかわかりません。
教えてください。

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2016/10/27 23:03:23
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答2件)

id:degucho No.1

回答回数281ベストアンサー獲得回数75

ポイント50pt

HANDLEではなくHMODULEで宣言してください
https://msdn.microsoft.com/ja-jp/library/cc429133.aspx

windows.hかwindef.hだったかに定義があったと思いますが
そのサイトは結構古いので
そのプログラム作成当時は互換性のある型だったのかも

id:mai_mai_mail

ありがとうございます。

2016/10/27 23:02:47
id:soqans No.2

回答回数9ベストアンサー獲得回数3

ポイント50pt

解決法としては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型は別の型の扱いになるようになってはいたと記憶しておりますが…

id:mai_mai_mail

ありがとうございます。

2016/10/27 23:03:03

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません