LoadLibraryW
関数シグネチャ
// KERNEL32.dll (Unicode / -W)
#include <windows.h>
HMODULE LoadLibraryW(
LPCWSTR lpLibFileName
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| lpLibFileName | LPCWSTR | in | モジュールの名前。これはライブラリモジュール(.dll ファイル)または実行可能モジュール(.exe ファイル)のいずれかを指定できます。
指定したモジュールが実行可能モジュールの場合、静的インポートは読み込まれません。
代わりに、 指定する名前はモジュールのファイル名であり、モジュール定義(.def)ファイルの LIBRARY キーワードで指定される、 ライブラリモジュール自体に格納された名前とは関係ありません。 文字列が完全なパスを指定している場合、関数はそのパスのみからモジュールを検索します。 文字列が相対パス、またはパスを含まないモジュール名を指定している場合、関数は標準の検索 方式を使用してモジュールを検索します。詳細については「解説」を参照してください。 関数がモジュールを見つけられない場合、関数は失敗します。パスを指定する際は、スラッシュ(/)ではなく バックスラッシュ(\)を必ず使用してください。パスの詳細については、 ファイルまたはディレクトリの名前付けを参照してください。 文字列がパスを含まないモジュール名を指定し、かつファイル名の拡張子が省略されている場合、関数は 既定のライブラリ拡張子 ".DLL" をモジュール名に付加します。関数がモジュール名に ".DLL" を 付加しないようにするには、モジュール名文字列の末尾にピリオド(.)を含めてください。 |
戻り値の型: HMODULE
公式ドキュメント
指定したモジュールを呼び出し元プロセスのアドレス空間に読み込みます。(LoadLibraryW)
戻り値
関数が成功すると、戻り値はモジュールへのハンドルになります。
関数が失敗すると、戻り値は NULL になります。拡張エラー情報を取得するには、 GetLastError を呼び出してください。
解説(Remarks)
DLL の読み込み中にローダーが表示するエラーメッセージを有効または無効にするには、 SetErrorMode 関数を使用します。
LoadLibrary は、ライブラリモジュールをプロセスのアドレス空間に読み込み、 DLL 関数のアドレスを取得するために GetProcAddress で 使用できるハンドルを返すために使用できます。 LoadLibrary は、他の実行可能モジュールを読み込むためにも使用できます。 たとえば、関数で .exe ファイルを指定して、 FindResource や LoadResource で使用できるハンドルを取得できます。ただし、 .exe ファイルを実行するために LoadLibrary を使用しないでください。 代わりに、CreateProcess 関数を使用してください。
指定したモジュールが呼び出し元プロセスにまだ読み込まれていない DLL である場合、システムはその DLL の DllMain 関数を DLL_PROCESS_ATTACH 値で呼び出します。 DllMain が TRUE を返すと、 LoadLibrary はモジュールへのハンドルを返します。 DllMain が FALSE を返すと、 システムはプロセスのアドレス空間から DLL をアンロードし、 LoadLibrary は NULL を返します。 DllMain から LoadLibrary を呼び出すのは安全ではありません。 詳細については、DllMain の「解説」セクションを参照してください。
モジュールハンドルはグローバルでも継承可能でもありません。あるプロセスによる LoadLibrary の呼び出しは、別のプロセスが使用できるハンドル (たとえば GetProcAddress の呼び出しに使用するもの)を生成しません。 他のプロセスは、GetProcAddress を呼び出す前に、対象のモジュールについて 独自に LoadLibrary を呼び出す必要があります。
lpFileName がパスを含まず、同じベース名と拡張子を持つ読み込み済みモジュールが複数ある場合、 関数は最初に読み込まれたモジュールへのハンドルを返します。
lpFileName パラメーターにファイル名の拡張子が指定されていない場合、既定の ライブラリ拡張子 .dll が付加されます。ただし、ファイル名文字列には末尾にピリオド(.)を含めて、 モジュール名に拡張子がないことを示すことができます。パスが指定されていない場合、関数は読み込み対象の モジュールのベース名と一致するベース名を持つ読み込み済みモジュールを検索します。名前が一致すれば、読み込みは成功します。 一致しなければ、関数はファイルを検索します。
最初に検索されるディレクトリは、呼び出し元プロセスの作成に使用されたイメージファイルを含むディレクトリです (詳細については CreateProcess 関数を参照してください)。これにより、プロセスに 関連付けられたプライベートなダイナミックリンクライブラリ(DLL)ファイルを、プロセスの インストールディレクトリを PATH 環境変数に追加することなく見つけられます。相対パスが 指定された場合、相対パス全体が DLL 検索パスリストの各トークンに付加されます。他のパスを検索せずに 相対パスからモジュールを読み込むには、 GetFullPathName を使用して非相対パスを取得し、 その非相対パスで LoadLibrary を呼び出してください。DLL の検索順序の詳細については、 ダイナミックリンクライブラリの検索順序を参照してください。
検索パスは SetDllDirectory 関数を使用して変更できます。 この方法は、SetCurrentDirectory を使用したり、 DLL への完全なパスをハードコーディングしたりする代わりに推奨されます。
パスが指定され、かつアプリケーション用のリダイレクトファイルがある場合、関数はアプリケーションの ディレクトリ内でモジュールを検索します。モジュールがアプリケーションのディレクトリに存在する場合、 LoadLibrary は指定されたパスを無視して、アプリケーションのディレクトリから モジュールを読み込みます。モジュールがアプリケーションのディレクトリに存在しない場合、 LoadLibrary は指定されたディレクトリからモジュールを読み込みます。詳細については、 ダイナミックリンクライブラリのリダイレクトを参照してください。
パス指定なしでアセンブリの名前を指定して LoadLibrary を呼び出し、 そのアセンブリがシステムの互換マニフェストに記載されている場合、呼び出しは 自動的に side-by-side アセンブリにリダイレクトされます。
システムは、すべての読み込み済みモジュールについてプロセスごとの参照 カウントを維持します。LoadLibrary を呼び出すと参照カウントが 増加します。FreeLibrary 関数または FreeLibraryAndExitThread 関数を呼び出すと 参照カウントが減少します。システムは、モジュールの参照カウントがゼロに達したとき、またはプロセスが 終了したとき(参照カウントに関係なく)にモジュールをアンロードします。
Windows Server 2003 および Windows XP: Visual C++ コンパイラは、スレッドローカル変数を宣言できる構文をサポートしています。 _declspec(thread) です。この構文を DLL 内で使用すると、Windows Vista より前のバージョンの Windows では LoadLibrary を使用してその DLL を明示的に読み込むことができません。 DLL が明示的に読み込まれる場合は、_declspec(thread) の代わりにスレッドローカル ストレージ関数を使用する必要があります。例については、 ダイナミックリンクライブラリでのスレッドローカルストレージの使用を参照してください。
セキュリティに関する解説
後続の LoadLibrary 呼び出しのために DLL へのパスを取得する目的で SearchPath 関数を使用しないでください。 SearchPath 関数は LoadLibrary とは異なる検索順序を使用し、 SetSearchPathMode を BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE とともに呼び出して明示的に有効化しない限り、 安全なプロセス検索モードを使用しません。そのため、 SearchPath は指定された DLL について、まずユーザーの現在の 作業ディレクトリを検索する可能性が高くなります。攻撃者が悪意のあるバージョンの DLL を現在の 作業ディレクトリにコピーしていた場合、SearchPath が取得するパスは その悪意のある DLL を指し、LoadLibrary がそれを読み込むことになります。DLL を検索する LoadLibrary 呼び出しに基づいて、オペレーティングシステムのバージョンについて 推測しないでください。DLL が正当に存在しないものの、悪意のあるバージョンの DLL が検索パスにある環境でアプリケーションが実行されている場合、悪意のあるバージョンの DLL が読み込まれる可能性があります。代わりに、 システムバージョンの取得で説明されている推奨 手法を使用してください。
例
例については、 実行時ダイナミックリンクの使用を参照してください。
libloaderapi.h ヘッダーは、UNICODE プリプロセッサ定数の定義に基づいてこの関数の ANSI 版または Unicode 版を自動的に選択するエイリアスとして LoadLibrary を定義します。エンコード中立のエイリアスの使用を、エンコード中立でないコードと混在させると、コンパイルエラーや実行時エラーを引き起こす不一致につながる可能性があります。詳細については、関数プロトタイプの規則を参照してください。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// KERNEL32.dll (Unicode / -W)
#include <windows.h>
HMODULE LoadLibraryW(
LPCWSTR lpLibFileName
);[DllImport("KERNEL32.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
static extern IntPtr LoadLibraryW(
[MarshalAs(UnmanagedType.LPWStr)] string lpLibFileName // LPCWSTR
);<DllImport("KERNEL32.dll", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function LoadLibraryW(
<MarshalAs(UnmanagedType.LPWStr)> lpLibFileName As String ' LPCWSTR
) As IntPtr
End Function' lpLibFileName : LPCWSTR
Declare PtrSafe Function LoadLibraryW Lib "kernel32" ( _
ByVal lpLibFileName As LongPtr) 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
LoadLibraryW = ctypes.windll.kernel32.LoadLibraryW
LoadLibraryW.restype = ctypes.c_void_p
LoadLibraryW.argtypes = [
wintypes.LPCWSTR, # lpLibFileName : LPCWSTR
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('KERNEL32.dll')
LoadLibraryW = Fiddle::Function.new(
lib['LoadLibraryW'],
[
Fiddle::TYPE_VOIDP, # lpLibFileName : LPCWSTR
],
Fiddle::TYPE_VOIDP)
# Wide strings: pass str.encode("UTF-16LE") + "\x00\x00"#[link(name = "kernel32")]
extern "system" {
fn LoadLibraryW(
lpLibFileName: *const u16 // LPCWSTR
) -> *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 LoadLibraryW([MarshalAs(UnmanagedType.LPWStr)] string lpLibFileName);
"@
$api = Add-Type -MemberDefinition $sig -Name 'KERNEL32_LoadLibraryW' -Namespace Win32 -PassThru
# $api::LoadLibraryW(lpLibFileName)#uselib "KERNEL32.dll"
#func global LoadLibraryW "LoadLibraryW" wptr
; LoadLibraryW lpLibFileName ; 戻り値は stat
; lpLibFileName : LPCWSTR -> "wptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "KERNEL32.dll"
#cfunc global LoadLibraryW "LoadLibraryW" wstr
; res = LoadLibraryW(lpLibFileName)
; lpLibFileName : LPCWSTR -> "wstr"; HMODULE LoadLibraryW(LPCWSTR lpLibFileName)
#uselib "KERNEL32.dll"
#cfunc global LoadLibraryW "LoadLibraryW" wstr
; res = LoadLibraryW(lpLibFileName)
; lpLibFileName : LPCWSTR -> "wstr"import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
kernel32 = windows.NewLazySystemDLL("KERNEL32.dll")
procLoadLibraryW = kernel32.NewProc("LoadLibraryW")
)
// lpLibFileName (LPCWSTR)
r1, _, err := procLoadLibraryW.Call(
uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(lpLibFileName))),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // HMODULEfunction LoadLibraryW(
lpLibFileName: PWideChar // LPCWSTR
): THandle; stdcall;
external 'KERNEL32.dll' name 'LoadLibraryW';result := DllCall("KERNEL32\LoadLibraryW"
, "WStr", lpLibFileName ; LPCWSTR
, "Ptr") ; return: HMODULE●LoadLibraryW(lpLibFileName) = DLL("KERNEL32.dll", "void* LoadLibraryW(char*)")
# 呼び出し: LoadLibraryW(lpLibFileName)
# lpLibFileName : LPCWSTR -> "char*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
# ※-W(Unicode)関数。なでしこ1はANSIのため -A 版の利用を推奨。const std = @import("std");
extern "kernel32" fn LoadLibraryW(
lpLibFileName: [*c]const u16 // LPCWSTR
) callconv(std.os.windows.WINAPI) ?*anyopaque;
// Unicode(-W): UTF-16LE のヌル終端バッファ([*c]const u16)を渡す。proc LoadLibraryW(
lpLibFileName: WideCString # LPCWSTR
): pointer {.importc: "LoadLibraryW", stdcall, dynlib: "KERNEL32.dll".}
# Unicode(-W): WideCString は newWideCString("...") で生成。pragma(lib, "kernel32");
extern(Windows)
void* LoadLibraryW(
const(wchar)* lpLibFileName // LPCWSTR
);ccall((:LoadLibraryW, "KERNEL32.dll"), stdcall, Ptr{Cvoid},
(Cwstring,),
lpLibFileName)
# lpLibFileName : LPCWSTR -> Cwstring
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
# Unicode(-W): Cwstring には transcode(UInt16, "...") 等で UTF-16 を渡す。local ffi = require("ffi")
ffi.cdef[[
void* LoadLibraryW(
const uint16_t* lpLibFileName);
]]
local kernel32 = ffi.load("kernel32")
-- kernel32.LoadLibraryW(lpLibFileName)
-- lpLibFileName : LPCWSTR
-- 構造体/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 LoadLibraryW = lib.func('__stdcall', 'LoadLibraryW', 'void *', ['str16']);
// LoadLibraryW(lpLibFileName)
// lpLibFileName : LPCWSTR -> 'str16'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。const lib = Deno.dlopen("KERNEL32.dll", {
LoadLibraryW: { parameters: ["buffer"], result: "pointer" },
});
// lib.symbols.LoadLibraryW(lpLibFileName)
// lpLibFileName : LPCWSTR -> "buffer"
// 文字列は "buffer"。Unicode(-W) は new TextEncoder() ではなく UTF-16LE のバイト列(末尾に \x00\x00)を Uint8Array で渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
void* LoadLibraryW(
const uint16_t* lpLibFileName);
C, "KERNEL32.dll");
// $ffi->LoadLibraryW(lpLibFileName);
// lpLibFileName : LPCWSTR
// 構造体/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 LoadLibraryW(
WString lpLibFileName // LPCWSTR
);
}
// Unicode(-W): WString(入力)/char[](出力)で UTF-16 をマーシャリング。@[Link("kernel32")]
lib LibKERNEL32
fun LoadLibraryW = LoadLibraryW(
lpLibFileName : UInt16* # LPCWSTR
) : Void*
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。import 'dart:ffi';
import 'package:ffi/ffi.dart';
typedef LoadLibraryWNative = Pointer<Void> Function(Pointer<Utf16>);
typedef LoadLibraryWDart = Pointer<Void> Function(Pointer<Utf16>);
final LoadLibraryW = DynamicLibrary.open('KERNEL32.dll')
.lookupFunction<LoadLibraryWNative, LoadLibraryWDart>('LoadLibraryW');
// lpLibFileName : LPCWSTR -> Pointer<Utf16>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function LoadLibraryW(
lpLibFileName: PWideChar // LPCWSTR
): THandle; stdcall;
external 'KERNEL32.dll' name 'LoadLibraryW';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "LoadLibraryW"
c_LoadLibraryW :: CWString -> IO (Ptr ())
-- lpLibFileName : LPCWSTR -> CWString
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let loadlibraryw =
foreign "LoadLibraryW"
((ptr uint16_t) @-> returning (ptr void))
(* lpLibFileName : LPCWSTR -> (ptr uint16_t) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)(cffi:define-foreign-library kernel32 (t "KERNEL32.dll"))
(cffi:use-foreign-library kernel32)
(cffi:defcfun ("LoadLibraryW" load-library-w :convention :stdcall) :pointer
(lp-lib-file-name (:string :encoding :utf-16le))) ; LPCWSTR
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $LoadLibraryW = Win32::API::More->new('KERNEL32',
'HANDLE LoadLibraryW(LPCWSTR lpLibFileName)');
# my $ret = $LoadLibraryW->Call($lpLibFileName);
# lpLibFileName : LPCWSTR -> LPCWSTR
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# Unicode(-W): LPCWSTR/LPWSTR は Win32::API が UTF-16 変換を行う。関連項目
- f LoadLibraryA (ANSI版) — 指定DLLをANSIパスで読み込みハンドルを返す。
- f LoadLibraryExW — フラグ指定でDLLをUnicodeパスから読み込む。
- f FindResourceW — モジュール内のリソースをUnicode名で検索する。
- f FreeLibrary — ロードしたDLLモジュールを解放する。
- f GetProcAddress — DLLからエクスポート関数のアドレスを取得する。
- f GetSystemDirectoryW — Windowsシステムディレクトリのパスを取得する(Unicode版)。
- f GetWindowsDirectoryW — Windowsディレクトリのパスを取得する(Unicode版)。
- f LoadResource — リソースをメモリへ読み込みハンドルを取得する。
- f SetDllDirectoryW — DLL検索ディレクトリをUnicodeパスで設定する。
- f SetErrorMode — 重大エラー時のシステム既定処理を制御するエラーモードを設定する。