2012-01-26 11 views
2

私は、Windows Vista以降(サポートされている)でCancelIoExを呼び出すアプリケーションを構築したいと思っています。オペレーティングシステムでサポートされている場合、条件付きで関数を実行するにはどうすればよいですか?

  1. Windows 7でアプリケーションをコンパイルしても、Windows XPで実行するとどうなりますか?実行時にはどうなりますか?何らかの負荷エラーが発生しますか?

  2. 実行時に使用されているオペレーティングシステムによって、アプリケーションにコードパスまたはコードパスを選択させるにはどうすればよいですか?サンプルコードを提供してください。

UPDATE:DLLは、Windows XP上で存在しますが、機能しないことに注意してください。

+0

[遅延ロードするDLL]の可能複製(http://stackoverflow.com/questions/1388388/遅延ロードdll) –

+0

@ GregHewgillでは、この場合遅延ロードは適切ではありません(動的ロードは)。それ以外にも、#1はカバーされていないので、これは正確な複製ではないと信じていますし、#2でどのOSが動作しているかを検出する方法も明確ではありません。 – Gili

+1

OSを検出する方法は、特定のOSを検出するのではなく、単にDLLをロードしようとします。バージョン検出ではなく、機能の検出が必要です。この機能については、こちらのドキュメントで説明しています。http://msdn.microsoft.com/en-us/library/151kt790.aspx –

答えて

2

はい、存在しないDLLエクスポートを参照するアプリケーションは読み込まれません。

OSバージョンに基づいて異なるパスを使用するようにコードを追加すると、存在しない関数への参照が残っているため、あまり役に立ちません。

代わりに、実行時に参照を解決する必要があります。

遅延ロードインポート(/DELAYLOADリンカフラグ付き)ですが、コアシステムDLL(kernel32など)ではサポートされていないと思います。

LoadLibraryおよびGetProcAddressのいずれかを使用します。コードはこのようなものですが、実際には、関数を呼び出すたびにではなく、アプリの起動時に一度ルックアップを実行します。

// Declare type of pointer to CancelIoEx function 
typedef BOOL (WINAPI *CancelIoExType)(HANDLE hFile, LPOVERLAPPED lpOverlapped); 

// Load module; won't fail because it's already imported 
HMODULE hKernel32 = LoadLibrary(L"kernel32.dll"); 
// Look up function address 
CancelIoExType pCancelIoEx = (CancelIoExType)GetProcAddress(hKernel32, "CancelIoEx"); 
// Do something with it 
if (pCancelIoEx) 
{ 
    // Function exists so call it 
    pCancelIoEx(hMyFile, pMyOverlapped); 
} 
else 
{ 
    // Function doesn't exist 
} 
+0

優れた答え。ありがとうございました! – Gili

1

実行時にシンボルを解決するために、あなたはLoadLibraryGetProcAddressを使用する必要があります。

場合
HMODULE kernel32 = LoadLibrary("kernel32.dll"); 
BOOL (WINAPI *pCancelIoEx)(HANDLE, LPOVERLAPPED) = GetProcAddress(kernel32, "CancelIoEx"); 

CancelIoExが利用できないことを、あなたはGetProcAddressからNULLバックを取得します。あなたはポインタ(あなたは一度だけ上記を行う必要があります)を持っていたら、あなたが正常にそれを呼び出すことができます。

pCancelIoEx(h, &lp); 
関連する問題