Win32 API 日本語リファレンス
ホームSystem.LibraryLoader › LoadLibraryExW

LoadLibraryExW

関数
フラグ指定でDLLをUnicodeパスから読み込む。
DLLKERNEL32.dll文字セットUnicode (-W)呼出規約winapiSetLastErrorあり対応OSWindows XP 以降

シグネチャ

// KERNEL32.dll  (Unicode / -W)
#include <windows.h>

HMODULE LoadLibraryExW(
    LPCWSTR lpLibFileName,
    HANDLE hFile,   // optional
    LOAD_LIBRARY_FLAGS dwFlags
);

パラメーター

名前方向説明
lpLibFileNameLPCWSTRin

ロードするモジュールのファイル名を指定する文字列です。この名前は、モジュール定義 (.def) ファイル内の LIBRARY キーワードで指定されるような、ライブラリモジュール自体に格納されている名前とは関係ありません。

モジュールは、ライブラリモジュール (.dll ファイル) または実行可能モジュール (.exe ファイル) のいずれかです。指定したモジュールが実行可能モジュールの場合、静的インポートはロードされず、代わりにモジュールは DONT_RESOLVE_DLL_REFERENCES が指定された場合と同じようにロードされます。詳細については dwFlags パラメーターを参照してください。

文字列がパスを含まないモジュール名を指定し、ファイル名拡張子が省略され、かつモジュール名に ピリオド文字 (.) が含まれていない場合、関数はモジュール名に既定のライブラリ拡張子 ".DLL" を付加します。 関数がモジュール名に ".DLL" を付加しないようにするには、モジュール名の文字列の末尾にピリオド文字 (.) を含めます。

文字列が完全修飾パスを指定する場合、関数はそのパスのみからモジュールを検索します。パスを 指定する際は、スラッシュ (/) ではなくバックスラッシュ (\) を使用してください。パスの詳細については、 ファイル、パス、名前空間の名前付けを参照してください。

文字列がパスを含まないモジュール名を指定し、同じベース名と拡張子を持つ複数のモジュールがロードされている場合、 関数は最初にロードされたモジュールのハンドルを返します。

文字列がパスを含まないモジュール名を指定し、同じ名前のモジュールがまだロードされていない場合、または 文字列が相対パスを含むモジュール名を指定する場合、関数は指定したモジュールを検索します。指定したモジュールをロードすることでシステムが他の関連 モジュールをロードする場合 (つまり、モジュールに依存関係がある場合) も、関数はモジュールを検索します。検索されるディレクトリとその検索順序は、 指定したパスと dwFlags パラメーターに依存します。詳細については「注釈」を参照してください。

関数がモジュールまたはその依存関係の 1 つを見つけられない場合、関数は失敗します。

hFileHANDLEoptionalこのパラメーターは将来の使用のために予約されています。NULL でなければなりません。
dwFlagsLOAD_LIBRARY_FLAGSin

モジュールのロード時に実行するアクションです。フラグを指定しない場合、この関数の動作は LoadLibrary 関数と同一になります。このパラメーターには、次の値のいずれかを指定できます。

意味
DONT_RESOLVE_DLL_REFERENCES
0x00000001
この値を使用し、実行可能モジュールが DLL の場合、システムはプロセスおよびスレッドの初期化と 終了のために DllMain を呼び出しません。また、システムは指定した モジュールが参照する追加の実行可能モジュールをロードしません。
注意 この値は使用しないでください。下位互換性のためにのみ提供されています。DLL 内のデータまたはリソースのみに アクセスする予定の場合は、LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE または LOAD_LIBRARY_AS_IMAGE_RESOURCE、あるいはその両方を使用してください。それ以外の場合は、 LoadLibrary 関数を使用してライブラリを DLL または実行可能モジュールとしてロードしてください。
LOAD_IGNORE_CODE_AUTHZ_LEVEL
0x00000010
この値を使用すると、システムは DLL に対して AppLocker ルールをチェックせず、 ソフトウェアの制限のポリシーを適用しません。 このアクションはロードされる DLL にのみ適用され、その依存関係には適用されません。この値は、 インストール中に展開された DLL を実行する必要があるセットアッププログラムでの使用が推奨されます。

Windows Server 2008 R2 および Windows 7: KB2532445 がインストールされているシステムでは、呼び出し元は "LocalSystem" または "TrustedInstaller" として実行されている必要があります。そうでない場合、システムはこのフラグを無視します。詳細については、ヘルプとサポートのナレッジベースの「Windows 7 または Windows Server 2008 R2 を実行しているコンピューターで Office マクロを使用して AppLocker ルールを回避できる」(https://support.microsoft.com/kb/2532445) を参照してください。

Windows Server 2008、Windows Vista、Windows Server 2003 および Windows XP: AppLocker は Windows 7 および Windows Server 2008 R2 で導入されました。

LOAD_LIBRARY_AS_DATAFILE
0x00000002
この値を使用すると、システムはファイルをデータファイルであるかのように呼び出し元プロセスの仮想アドレス空間に マップします。マップされたファイルの実行や実行準備は行われません。したがって、この DLL に対して GetModuleFileNameGetModuleHandleGetProcAddress のような関数を呼び出すことはできません。この値を使用すると、 読み取り専用メモリへの書き込みがアクセス違反を発生させます。DLL からメッセージまたはリソースを抽出する目的でのみ DLL をロードしたい場合に、 このフラグを使用します。

この値は LOAD_LIBRARY_AS_IMAGE_RESOURCE と組み合わせて使用できます。詳細については 「注釈」を参照してください。

LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
0x00000040
LOAD_LIBRARY_AS_DATAFILE と似ていますが、DLL ファイルが呼び出し元プロセスに対して 排他的な書き込みアクセスで開かれる点が異なります。他のプロセスは、その DLL ファイルが使用中の間、書き込みアクセスのために 開くことはできません。ただし、他のプロセスがその DLL を開くことは依然として可能です。

この値は LOAD_LIBRARY_AS_IMAGE_RESOURCE と組み合わせて使用できます。詳細については 「注釈」を参照してください。

Windows Server 2003 および Windows XP: この値は Windows Vista までサポートされていません。

LOAD_LIBRARY_AS_IMAGE_RESOURCE
0x00000020
この値を使用すると、システムはファイルをイメージファイルとしてプロセスの仮想アドレス空間にマップします。 ただし、ローダーは静的インポートをロードせず、その他の通常の初期化手順も実行しません。DLL からメッセージまたはリソースを抽出する目的でのみ DLL を ロードしたい場合に、このフラグを使用します。

アプリケーションがファイルのインメモリレイアウトがイメージのものであることに依存していない限り、この値は LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE または LOAD_LIBRARY_AS_DATAFILE のいずれかと組み合わせて使用してください。詳細については「注釈」セクションを参照してください。

Windows Server 2003 および Windows XP: この値は Windows Vista までサポートされていません。

LOAD_LIBRARY_SEARCH_APPLICATION_DIR
0x00000200
この値を使用すると、DLL とその依存関係についてアプリケーションのインストールディレクトリが検索されます。 標準の検索パス内のディレクトリは検索されません。この値は LOAD_WITH_ALTERED_SEARCH_PATH と組み合わせることはできません。

Windows 7、Windows Server 2008 R2、Windows Vista および Windows Server 2008: この値には KB2533623 のインストールが 必要です。

Windows Server 2003 および Windows XP: この値はサポートされていません。

LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
0x00001000
この値は LOAD_LIBRARY_SEARCH_APPLICATION_DIRLOAD_LIBRARY_SEARCH_SYSTEM32、および LOAD_LIBRARY_SEARCH_USER_DIRS の組み合わせです。標準の検索パス内のディレクトリは 検索されません。この値は LOAD_WITH_ALTERED_SEARCH_PATH と組み合わせることはできません。

この値は、アプリケーションが DLL 検索パスに含めるべきディレクトリの推奨される最大数を表します。

Windows 7、Windows Server 2008 R2、Windows Vista および Windows Server 2008: この値には KB2533623 のインストールが 必要です。

Windows Server 2003 および Windows XP: この値はサポートされていません。

LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
0x00000100
この値を使用すると、DLL を含むディレクトリが、その DLL の依存関係を検索するディレクトリの リストの先頭に一時的に追加されます。標準の検索パス内のディレクトリは検索されません。

lpFileName パラメーターには完全修飾パスを指定する必要があります。この値は LOAD_WITH_ALTERED_SEARCH_PATH と組み合わせることはできません。

たとえば、Lib2.dll が C:\Dir1\Lib1.dll の依存関係である場合、この値を指定して Lib1.dll をロードすると、システムは Lib2.dll を C:\Dir1 のみで検索します。Lib2.dll を C:\Dir1 と DLL 検索パス内のすべてのディレクトリで検索するには、この値を LOAD_LIBRARY_DEFAULT_DIRS と組み合わせます。

Windows 7、Windows Server 2008 R2、Windows Vista および Windows Server 2008: この値には KB2533623 のインストールが 必要です。

Windows Server 2003 および Windows XP: この値はサポートされていません。

LOAD_LIBRARY_SEARCH_SYSTEM32
0x00000800
この値を使用すると、DLL とその依存関係について %windows%\system32 が検索されます。 標準の検索パス内のディレクトリは検索されません。この値は LOAD_WITH_ALTERED_SEARCH_PATH と組み合わせることはできません。

Windows 7、Windows Server 2008 R2、Windows Vista および Windows Server 2008: この値には KB2533623 のインストールが 必要です。

Windows Server 2003 および Windows XP: この値はサポートされていません。

LOAD_LIBRARY_SEARCH_USER_DIRS
0x00000400
この値を使用すると、DLL とその依存関係について、 AddDllDirectory 関数または SetDllDirectory 関数を使用して追加された ディレクトリが検索されます。複数のディレクトリが追加されている場合、ディレクトリが 検索される順序は不定です。標準の検索パス内のディレクトリは検索されません。この値は LOAD_WITH_ALTERED_SEARCH_PATH と組み合わせることはできません。

Windows 7、Windows Server 2008 R2、Windows Vista および Windows Server 2008: この値には KB2533623 のインストールが 必要です。

Windows Server 2003 および Windows XP: この値はサポートされていません。

LOAD_WITH_ALTERED_SEARCH_PATH
0x00000008
この値を使用し、lpFileName が絶対パスを指定する場合、システムは指定したモジュールが ロードを引き起こす関連実行可能モジュールを見つけるために、「注釈」セクションで説明する代替ファイル検索方式を使用します。この値を使用し、lpFileName が相対パスを指定する場合、動作は未定義です。

この値を使用しない場合、または lpFileName がパスを指定しない場合、システムは 指定したモジュールがロードを引き起こす関連実行可能モジュールを見つけるために、「注釈」セクションで説明する標準検索方式を使用します。

この値は、どの LOAD_LIBRARY_SEARCH フラグとも組み合わせることはできません。

LOAD_LIBRARY_REQUIRE_SIGNED_TARGET
0x00000080
バイナリイメージのデジタル署名をロード時にチェックする必要があることを指定します。

この値には Windows 8.1、Windows 10 以降が必要です。

LOAD_LIBRARY_SAFE_CURRENT_DIRS
0x00002000
この値を使用すると、現在のディレクトリから実行用に DLL をロードすることは、それが安全なロードリスト内のディレクトリ配下にある場合にのみ許可されます。

戻り値の型: HMODULE

公式ドキュメント

指定したモジュールを呼び出し元プロセスのアドレス空間にロードします。(LoadLibraryExW)

戻り値

関数が成功した場合、戻り値はロードされたモジュールのハンドルです。

関数が失敗した場合、戻り値は NULL です。拡張エラー情報を取得するには、 GetLastError を呼び出します。

解説(Remarks)

LoadLibraryEx 関数は LoadLibrary 関数と非常によく似ています。違いは、LoadLibraryEx が提供する一連の オプションの動作にあります。

これらのオプションの動作は dwFlags パラメーターを設定して選択します。dwFlags が 0 の場合、 LoadLibraryExLoadLibrary と同一の動作をします。

呼び出し元プロセスは、LoadLibraryEx が返したハンドルを使用して、 GetProcAddressFindResourceLoadResource 関数の呼び出しでモジュールを識別できます。

DLL のロード中にローダーが表示するエラーメッセージを有効または無効にするには、 SetErrorMode 関数を使用します。

DllMain から LoadLibraryEx を呼び出すことは安全ではありません。詳細については、 DllMain の「注釈」セクションを参照してください。

Visual C++: Visual C++ コンパイラは、スレッドローカル変数を宣言できる構文をサポートしています: _declspec(thread)。この構文を DLL で使用すると、Windows Vista より前のバージョンの Windows では LoadLibraryEx を使用して DLL を明示的にロードできなくなります。DLL が明示的にロードされる場合は、 _declspec(thread) の代わりにスレッドローカルストレージ関数を使用する必要があります。例については、 ダイナミックリンクライブラリでのスレッドローカルストレージの使用を参照してください。

DLL をデータファイルまたはイメージリソースとしてロードする

LOAD_LIBRARY_AS_DATAFILELOAD_LIBRARY_AS_DATAFILE_EXCLUSIVELOAD_LIBRARY_AS_IMAGE_RESOURCE の各値は、プロセスごとの参照カウントと指定したモジュールの ロードに影響します。これらの値のいずれかが dwFlags パラメーターに指定された場合、ローダーはモジュールがプロセスによって実行可能 DLL としてすでにロードされているかどうかをチェックします。すでにロードされている場合、 モジュールは呼び出し元プロセスの仮想アドレス空間にすでにマップされていることを意味します。この場合、 LoadLibraryEx は DLL のハンドルを返し、DLL の参照カウントを インクリメントします。DLL モジュールが DLL としてまだロードされていない場合、システムは モジュールを実行可能 DLL としてではなくデータまたはイメージファイルとしてマップします。この場合、 LoadLibraryEx はロードされたデータまたは イメージファイルのハンドルを返しますが、モジュールの参照カウントをインクリメントせず、CreateToolhelp32SnapshotEnumProcessModules のような関数からモジュールを可視化しません。

同じファイルに対して LOAD_LIBRARY_AS_DATAFILELOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE、または LOAD_LIBRARY_AS_IMAGE_RESOURCE を指定して LoadLibraryEx が 2 回呼び出された場合、 そのファイルに対して 2 つの別々のマッピングが作成されます。

LOAD_LIBRARY_AS_IMAGE_RESOURCE の値を使用すると、モジュールはポータブル実行可能 (PE) セクションのアライメント拡張を使用してイメージとしてロードされます。相対仮想アドレス (RVA) を ディスクアドレスにマップする必要がないため、モジュールからリソースをより速く取得できます。 LOAD_LIBRARY_AS_IMAGE_RESOURCE を指定すると、ロード中に他のプロセスがモジュールを 変更できなくなります。

アプリケーションが特定のイメージマッピング特性に依存していない限り、 LOAD_LIBRARY_AS_IMAGE_RESOURCE の値は LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE または LOAD_LIBRARY_AS_DATAFILE のいずれかと組み合わせて使用してください。これにより、ローダーはモジュールを イメージリソースとしてロードするかデータファイルとしてロードするかを選択でき、システムがページをより効果的に 共有できるオプションを選択します。FindResource のような リソース関数は、どちらのマッピングでも使用できます。

モジュールがどのようにロードされたかを判定するには、次のマクロのいずれかを使用して LoadLibraryEx が返したハンドルをテストします。

#define LDR_IS_DATAFILE(handle)      (((ULONG_PTR)(handle)) &  (ULONG_PTR)1)
#define LDR_IS_IMAGEMAPPING(handle)  (((ULONG_PTR)(handle)) & (ULONG_PTR)2)
#define LDR_IS_RESOURCE(handle)      (LDR_IS_IMAGEMAPPING(handle) || LDR_IS_DATAFILE(handle))

次の表はこれらのマクロを説明しています。

マクロ 説明
LDR_IS_DATAFILE(handle) このマクロが TRUE を返す場合、モジュールはデータファイルとしてロードされました (LOAD_LIBRARY_AS_DATAFILE または LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)。
LDR_IS_IMAGEMAPPING(handle) このマクロが TRUE を返す場合、モジュールはイメージファイルとしてロードされました (LOAD_LIBRARY_AS_IMAGE_RESOURCE)。
LDR_IS_RESOURCE(handle) このマクロが TRUE を返す場合、モジュールはデータファイルまたは イメージファイルのいずれかとしてロードされました。

ロードされたモジュールを解放するには、モジュールのロードによって参照カウントがインクリメントされたかどうかにかかわらず、 FreeLibrary 関数を使用します。モジュールがデータ またはイメージファイルとしてロードされた場合、マッピングは破棄されますが参照カウントはデクリメントされません。それ以外の場合は、DLL の 参照カウントがデクリメントされます。したがって、LoadLibraryEx が返した任意のハンドルで FreeLibrary を呼び出すことは安全です。

DLL と依存関係の検索

検索パスとは、DLL を検索するディレクトリのセットです。 LoadLibraryEx 関数は、標準検索パスまたは代替検索パスを使用して DLL を検索できます。あるいは、 SetDefaultDllDirectories 関数と AddDllDirectory 関数で確立したプロセス固有の検索パスを 使用することもできます。ディレクトリの一覧とその検索順序については、 ダイナミックリンクライブラリの検索順序を参照してください。

LoadLibraryEx 関数は、次の場合に標準検索 パスを使用します。

lpFileName が相対パスを指定する場合、相対パス全体が DLL 検索パス内の すべてのトークンに付加されます。他のパスを検索せずに相対パスからモジュールをロードするには、 GetFullPathName を使用して非相対パスを取得し、その非相対パスで LoadLibraryEx を呼び出します。モジュールが データファイルとしてロードされ、相対パスが "." または ".." で始まる場合、その相対パスは絶対パスとして扱われます。

lpFileName が絶対パスを指定し、dwFlagsLOAD_WITH_ALTERED_SEARCH_PATH に設定されている場合、 LoadLibraryEx は代替検索パスを使用します。 LOAD_WITH_ALTERED_SEARCH_PATH フラグが設定され、lpFileName が相対パスを指定する場合、動作は未定義です。

SetDllDirectory 関数を使用して検索パスを変更できます。 この解決策は、SetCurrentDirectory を使用したり、DLL への完全パスを ハードコードしたりするよりも優れています。ただし、 SetDllDirectory を使用すると、指定したディレクトリが検索パスに含まれている間は安全な DLL 検索 モードが事実上無効になり、スレッドセーフではない点に注意してください。可能であれば、 AddDllDirectory を使用して既定のプロセス 検索パスを変更するのが最善です。詳細については、 ダイナミックリンクライブラリの検索順序を参照してください。

アプリケーションは、LOAD_LIBRARY_SEARCH_* フラグを使用することで、単一の LoadLibraryEx 呼び出しに対して検索するディレクトリを 指定できます。複数の LOAD_LIBRARY_SEARCH フラグが指定された場合、ディレクトリは次の 順序で検索されます。

Windows 7、Windows Server 2008 R2、Windows Vista および Windows Server 2008: LOAD_LIBRARY_SEARCH_* フラグは、 KB2533623 がインストールされているシステムで利用できます。フラグが利用可能かどうかを判定するには、 GetProcAddress を使用して AddDllDirectoryRemoveDllDirectory、または SetDefaultDllDirectories 関数のアドレスを取得します。 GetProcAddress が成功した場合、 LOAD_LIBRARY_SEARCH_* フラグを LoadLibraryEx で使用できます。

アプリケーションが SetDefaultDllDirectories 関数を使用して プロセスの DLL 検索パスを確立しており、LOAD_LIBRARY_SEARCH_* フラグがいずれも使用されていない場合、LoadLibraryEx 関数は 標準検索パスの代わりにプロセス DLL 検索パスを使用します。

パスが指定され、アプリケーションに関連付けられたリダイレクトファイルがある場合、 LoadLibraryEx 関数はアプリケーションディレクトリでモジュールを 検索します。モジュールがアプリケーションディレクトリに存在する場合、 LoadLibraryEx はパス指定を無視し、 アプリケーションディレクトリからモジュールをロードします。モジュールがアプリケーションディレクトリに存在しない場合、 関数は指定したディレクトリからモジュールをロードします。詳細については、 ダイナミックリンクライブラリのリダイレクトを参照してください。

パス指定なしでアセンブリの名前を指定して LoadLibraryEx を呼び出し、 そのアセンブリがシステム互換マニフェストに記載されている場合、呼び出しは 自動的に side-by-side アセンブリにリダイレクトされます。

セキュリティに関する注釈

LOAD_LIBRARY_AS_DATAFILE は、ロード中に他のプロセスがモジュールを 変更することを防止しません。これによりアプリケーションの安全性が低下する可能性があるため、モジュールをデータファイルとしてロードする際は、 特に LOAD_LIBRARY_AS_DATAFILE を使用する必要がある場合を除き、 LOAD_LIBRARY_AS_DATAFILE の代わりに LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE を使用してください。 LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE を指定すると、ロード中に他のプロセスがモジュールを 変更できなくなります。同じ呼び出しで LOAD_LIBRARY_AS_DATAFILELOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE を指定しないでください。

後続の LoadLibraryEx 呼び出しのために DLL へのパスを取得する目的で SearchPath 関数を使用しないでください。 SearchPath 関数は LoadLibraryEx とは異なる検索順序を使用し、 SetSearchPathModeBASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE で呼び出して明示的に有効化しない限り、安全なプロセス検索 モードを使用しません。したがって、 SearchPath は指定した DLL についてユーザーの現在の作業 ディレクトリを最初に検索する可能性が高くなります。攻撃者が悪意のあるバージョンの DLL を 現在の作業ディレクトリにコピーしている場合、 SearchPath が取得するパスはその悪意のある DLL を指し、 LoadLibraryEx はそれをロードしてしまいます。

DLL を検索する LoadLibraryEx 呼び出しに基づいて オペレーティングシステムのバージョンを想定しないでください。 アプリケーションが、DLL が正規には存在しないが悪意のあるバージョンの DLL が検索パスにある環境で実行されている場合、悪意のあるバージョンの DLL がロードされる可能性があります。代わりに、 システムバージョンの取得で説明されている推奨される 手法を使用してください。

DLL のセキュリティ問題に関する一般的な説明については、 ダイナミックリンクライブラリのセキュリティを参照してください。

例については、 エラーコード番号のテキストの検索を参照してください。

メモ

libloaderapi.h ヘッダーは、LoadLibraryEx を、UNICODE プリプロセッサ定数の定義に基づいてこの関数の ANSI 版または Unicode 版を自動的に選択するエイリアスとして定義します。エンコーディング中立なエイリアスの使用を、エンコーディング中立でないコードと混在させると、コンパイルエラーやランタイムエラーを引き起こす不整合につながる可能性があります。詳細については、関数プロトタイプの規則を参照してください。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// KERNEL32.dll  (Unicode / -W)
#include <windows.h>

HMODULE LoadLibraryExW(
    LPCWSTR lpLibFileName,
    HANDLE hFile,   // optional
    LOAD_LIBRARY_FLAGS dwFlags
);
[DllImport("KERNEL32.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
static extern IntPtr LoadLibraryExW(
    [MarshalAs(UnmanagedType.LPWStr)] string lpLibFileName,   // LPCWSTR
    IntPtr hFile,   // HANDLE optional
    uint dwFlags   // LOAD_LIBRARY_FLAGS
);
<DllImport("KERNEL32.dll", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function LoadLibraryExW(
    <MarshalAs(UnmanagedType.LPWStr)> lpLibFileName As String,   ' LPCWSTR
    hFile As IntPtr,   ' HANDLE optional
    dwFlags As UInteger   ' LOAD_LIBRARY_FLAGS
) As IntPtr
End Function
' lpLibFileName : LPCWSTR
' hFile : HANDLE optional
' dwFlags : LOAD_LIBRARY_FLAGS
Declare PtrSafe Function LoadLibraryExW Lib "kernel32" ( _
    ByVal lpLibFileName As LongPtr, _
    ByVal hFile As LongPtr, _
    ByVal dwFlags As Long) As LongPtr
' Unicode(W): 文字列は ByVal As LongPtr とし StrPtr(unicodeStr) を渡す
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

LoadLibraryExW = ctypes.windll.kernel32.LoadLibraryExW
LoadLibraryExW.restype = ctypes.c_void_p
LoadLibraryExW.argtypes = [
    wintypes.LPCWSTR,  # lpLibFileName : LPCWSTR
    wintypes.HANDLE,  # hFile : HANDLE optional
    wintypes.DWORD,  # dwFlags : LOAD_LIBRARY_FLAGS
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('KERNEL32.dll')
LoadLibraryExW = Fiddle::Function.new(
  lib['LoadLibraryExW'],
  [
    Fiddle::TYPE_VOIDP,  # lpLibFileName : LPCWSTR
    Fiddle::TYPE_VOIDP,  # hFile : HANDLE optional
    -Fiddle::TYPE_INT,  # dwFlags : LOAD_LIBRARY_FLAGS
  ],
  Fiddle::TYPE_VOIDP)
# Wide strings: pass str.encode("UTF-16LE") + "\x00\x00"
#[link(name = "kernel32")]
extern "system" {
    fn LoadLibraryExW(
        lpLibFileName: *const u16,  // LPCWSTR
        hFile: *mut core::ffi::c_void,  // HANDLE optional
        dwFlags: u32  // LOAD_LIBRARY_FLAGS
    ) -> *mut core::ffi::c_void;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("KERNEL32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr LoadLibraryExW([MarshalAs(UnmanagedType.LPWStr)] string lpLibFileName, IntPtr hFile, uint dwFlags);
"@
$api = Add-Type -MemberDefinition $sig -Name 'KERNEL32_LoadLibraryExW' -Namespace Win32 -PassThru
# $api::LoadLibraryExW(lpLibFileName, hFile, dwFlags)
#uselib "KERNEL32.dll"
#func global LoadLibraryExW "LoadLibraryExW" wptr, wptr, wptr
; LoadLibraryExW lpLibFileName, hFile, dwFlags   ; 戻り値は stat
; lpLibFileName : LPCWSTR -> "wptr"
; hFile : HANDLE optional -> "wptr"
; dwFlags : LOAD_LIBRARY_FLAGS -> "wptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
#uselib "KERNEL32.dll"
#cfunc global LoadLibraryExW "LoadLibraryExW" wstr, sptr, int
; res = LoadLibraryExW(lpLibFileName, hFile, dwFlags)
; lpLibFileName : LPCWSTR -> "wstr"
; hFile : HANDLE optional -> "sptr"
; dwFlags : LOAD_LIBRARY_FLAGS -> "int"
; HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, LOAD_LIBRARY_FLAGS dwFlags)
#uselib "KERNEL32.dll"
#cfunc global LoadLibraryExW "LoadLibraryExW" wstr, intptr, int
; res = LoadLibraryExW(lpLibFileName, hFile, dwFlags)
; lpLibFileName : LPCWSTR -> "wstr"
; hFile : HANDLE optional -> "intptr"
; dwFlags : LOAD_LIBRARY_FLAGS -> "int"
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	kernel32 = windows.NewLazySystemDLL("KERNEL32.dll")
	procLoadLibraryExW = kernel32.NewProc("LoadLibraryExW")
)

// lpLibFileName (LPCWSTR), hFile (HANDLE optional), dwFlags (LOAD_LIBRARY_FLAGS)
r1, _, err := procLoadLibraryExW.Call(
	uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(lpLibFileName))),
	uintptr(hFile),
	uintptr(dwFlags),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // HMODULE
function LoadLibraryExW(
  lpLibFileName: PWideChar;   // LPCWSTR
  hFile: THandle;   // HANDLE optional
  dwFlags: DWORD   // LOAD_LIBRARY_FLAGS
): THandle; stdcall;
  external 'KERNEL32.dll' name 'LoadLibraryExW';
result := DllCall("KERNEL32\LoadLibraryExW"
    , "WStr", lpLibFileName   ; LPCWSTR
    , "Ptr", hFile   ; HANDLE optional
    , "UInt", dwFlags   ; LOAD_LIBRARY_FLAGS
    , "Ptr")   ; return: HMODULE
●LoadLibraryExW(lpLibFileName, hFile, dwFlags) = DLL("KERNEL32.dll", "void* LoadLibraryExW(char*, void*, dword)")
# 呼び出し: LoadLibraryExW(lpLibFileName, hFile, dwFlags)
# lpLibFileName : LPCWSTR -> "char*"
# hFile : HANDLE optional -> "void*"
# dwFlags : LOAD_LIBRARY_FLAGS -> "dword"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
# ※-W(Unicode)関数。なでしこ1はANSIのため -A 版の利用を推奨。
const std = @import("std");

extern "kernel32" fn LoadLibraryExW(
    lpLibFileName: [*c]const u16, // LPCWSTR
    hFile: ?*anyopaque, // HANDLE optional
    dwFlags: u32 // LOAD_LIBRARY_FLAGS
) callconv(std.os.windows.WINAPI) ?*anyopaque;
// Unicode(-W): UTF-16LE のヌル終端バッファ([*c]const u16)を渡す。
proc LoadLibraryExW(
    lpLibFileName: WideCString,  # LPCWSTR
    hFile: pointer,  # HANDLE optional
    dwFlags: uint32  # LOAD_LIBRARY_FLAGS
): pointer {.importc: "LoadLibraryExW", stdcall, dynlib: "KERNEL32.dll".}
# Unicode(-W): WideCString は newWideCString("...") で生成。
pragma(lib, "kernel32");
extern(Windows)
void* LoadLibraryExW(
    const(wchar)* lpLibFileName,   // LPCWSTR
    void* hFile,   // HANDLE optional
    uint dwFlags   // LOAD_LIBRARY_FLAGS
);
ccall((:LoadLibraryExW, "KERNEL32.dll"), stdcall, Ptr{Cvoid},
      (Cwstring, Ptr{Cvoid}, UInt32),
      lpLibFileName, hFile, dwFlags)
# lpLibFileName : LPCWSTR -> Cwstring
# hFile : HANDLE optional -> Ptr{Cvoid}
# dwFlags : LOAD_LIBRARY_FLAGS -> UInt32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
# Unicode(-W): Cwstring には transcode(UInt16, "...") 等で UTF-16 を渡す。
local ffi = require("ffi")
ffi.cdef[[
void* LoadLibraryExW(
    const uint16_t* lpLibFileName,
    void* hFile,
    uint32_t dwFlags);
]]
local kernel32 = ffi.load("kernel32")
-- kernel32.LoadLibraryExW(lpLibFileName, hFile, dwFlags)
-- lpLibFileName : LPCWSTR
-- hFile : HANDLE optional
-- dwFlags : LOAD_LIBRARY_FLAGS
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
-- Unicode(-W): uint16_t* には UTF-16LE のバッファ(ffi.new("uint16_t[?]", ...))を渡す。
const koffi = require('koffi');
const lib = koffi.load('KERNEL32.dll');
const LoadLibraryExW = lib.func('__stdcall', 'LoadLibraryExW', 'void *', ['str16', 'void *', 'uint32_t']);
// LoadLibraryExW(lpLibFileName, hFile, dwFlags)
// lpLibFileName : LPCWSTR -> 'str16'
// hFile : HANDLE optional -> 'void *'
// dwFlags : LOAD_LIBRARY_FLAGS -> 'uint32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("KERNEL32.dll", {
  LoadLibraryExW: { parameters: ["buffer", "pointer", "u32"], result: "pointer" },
});
// lib.symbols.LoadLibraryExW(lpLibFileName, hFile, dwFlags)
// lpLibFileName : LPCWSTR -> "buffer"
// hFile : HANDLE optional -> "pointer"
// dwFlags : LOAD_LIBRARY_FLAGS -> "u32"
// 文字列は "buffer"。Unicode(-W) は new TextEncoder() ではなく UTF-16LE のバイト列(末尾に \x00\x00)を Uint8Array で渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
void* LoadLibraryExW(
    const uint16_t* lpLibFileName,
    void* hFile,
    uint32_t dwFlags);
C, "KERNEL32.dll");
// $ffi->LoadLibraryExW(lpLibFileName, hFile, dwFlags);
// lpLibFileName : LPCWSTR
// hFile : HANDLE optional
// dwFlags : LOAD_LIBRARY_FLAGS
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Kernel32 extends StdCallLibrary {
    Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class, W32APIOptions.UNICODE_OPTIONS);
    Pointer LoadLibraryExW(
        WString lpLibFileName,   // LPCWSTR
        Pointer hFile,   // HANDLE optional
        int dwFlags   // LOAD_LIBRARY_FLAGS
    );
}
// Unicode(-W): WString(入力)/char[](出力)で UTF-16 をマーシャリング。
@[Link("kernel32")]
lib LibKERNEL32
  fun LoadLibraryExW = LoadLibraryExW(
    lpLibFileName : UInt16*,   # LPCWSTR
    hFile : Void*,   # HANDLE optional
    dwFlags : UInt32   # LOAD_LIBRARY_FLAGS
  ) : Void*
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef LoadLibraryExWNative = Pointer<Void> Function(Pointer<Utf16>, Pointer<Void>, Uint32);
typedef LoadLibraryExWDart = Pointer<Void> Function(Pointer<Utf16>, Pointer<Void>, int);
final LoadLibraryExW = DynamicLibrary.open('KERNEL32.dll')
    .lookupFunction<LoadLibraryExWNative, LoadLibraryExWDart>('LoadLibraryExW');
// lpLibFileName : LPCWSTR -> Pointer<Utf16>
// hFile : HANDLE optional -> Pointer<Void>
// dwFlags : LOAD_LIBRARY_FLAGS -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function LoadLibraryExW(
  lpLibFileName: PWideChar;   // LPCWSTR
  hFile: THandle;   // HANDLE optional
  dwFlags: DWORD   // LOAD_LIBRARY_FLAGS
): THandle; stdcall;
  external 'KERNEL32.dll' name 'LoadLibraryExW';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "LoadLibraryExW"
  c_LoadLibraryExW :: CWString -> Ptr () -> Word32 -> IO (Ptr ())
-- lpLibFileName : LPCWSTR -> CWString
-- hFile : HANDLE optional -> Ptr ()
-- dwFlags : LOAD_LIBRARY_FLAGS -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let loadlibraryexw =
  foreign "LoadLibraryExW"
    ((ptr uint16_t) @-> (ptr void) @-> uint32_t @-> returning (ptr void))
(* lpLibFileName : LPCWSTR -> (ptr uint16_t) *)
(* hFile : HANDLE optional -> (ptr void) *)
(* dwFlags : LOAD_LIBRARY_FLAGS -> uint32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library kernel32 (t "KERNEL32.dll"))
(cffi:use-foreign-library kernel32)

(cffi:defcfun ("LoadLibraryExW" load-library-ex-w :convention :stdcall) :pointer
  (lp-lib-file-name (:string :encoding :utf-16le))   ; LPCWSTR
  (h-file :pointer)   ; HANDLE optional
  (dw-flags :uint32))   ; LOAD_LIBRARY_FLAGS
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $LoadLibraryExW = Win32::API::More->new('KERNEL32',
    'HANDLE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)');
# my $ret = $LoadLibraryExW->Call($lpLibFileName, $hFile, $dwFlags);
# lpLibFileName : LPCWSTR -> LPCWSTR
# hFile : HANDLE optional -> HANDLE
# dwFlags : LOAD_LIBRARY_FLAGS -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# Unicode(-W): LPCWSTR/LPWSTR は Win32::API が UTF-16 変換を行う。

関連項目

文字セット違い
類似 API
公式の関連項目
使用する型