人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

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

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

●質問者: mai_mai_mail
●カテゴリ:コンピュータ
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● degucho
●50ポイント

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

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


mai_mai_mailさんのコメント
ありがとうございます。

2 ● soqans
●50ポイント

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


mai_mai_mailさんのコメント
ありがとうございます。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ