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

LoadLibraryA

関数
指定DLLをANSIパスで読み込みハンドルを返す。
DLLKERNEL32.dll文字セットANSI (-A)呼出規約winapiSetLastErrorあり対応OSWindows XP 以降

シグネチャ

// KERNEL32.dll  (ANSI / -A)
#include <windows.h>

HMODULE LoadLibraryA(
    LPCSTR lpLibFileName
);

パラメーター

名前方向説明
lpLibFileNameLPCSTRin

モジュールの名前。ライブラリモジュール(.dll ファイル)または実行可能モジュール(.exe ファイル)のいずれかを指定できます。 指定したモジュールが実行可能モジュールの場合、静的インポートはロードされません。 代わりに、DONT_RESOLVE_DLL_REFERENCES フラグを指定した LoadLibraryEx による場合と同様にモジュールがロードされます。

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

文字列がフルパスを指定している場合、関数はそのパスのみからモジュールを検索します。

文字列が相対パスまたはパスなしのモジュール名を指定している場合、関数は標準の検索方法を用いてモジュールを探します。詳細については「解説」を参照してください。

関数がモジュールを見つけられない場合、関数は失敗します。パスを指定する際は、スラッシュ(/)ではなくバックスラッシュ(\)を使用してください。パスの詳細については、 ファイルまたはディレクトリの名前付けを参照してください。

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

戻り値の型: HMODULE

公式ドキュメント

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

戻り値

関数が成功すると、戻り値はモジュールへのハンドルになります。

関数が失敗すると、戻り値は NULL になります。拡張エラー情報を取得するには、 GetLastError を呼び出してください。

解説(Remarks)

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

LoadLibrary は、ライブラリモジュールをプロセスのアドレス空間にロードし、 GetProcAddress で DLL 関数のアドレスを取得するために使用できるハンドルを返すために使用できます。 LoadLibrary は、その他の実行可能モジュールをロードするためにも使用できます。たとえば、.exe ファイルを指定して、 FindResourceLoadResource で使用できるハンドルを取得できます。ただし、.exe ファイルを実行するために LoadLibrary を使用しないでください。代わりに CreateProcess 関数を使用します。

指定したモジュールが、呼び出し元プロセスにまだロードされていない DLL の場合、システムはその DLL の DllMain 関数を DLL_PROCESS_ATTACH 値で呼び出します。 DllMainTRUE を返すと、 LoadLibrary はモジュールへのハンドルを返します。 DllMainFALSE を返すと、 システムはその DLL をプロセスのアドレス空間からアンロードし、 LoadLibraryNULL を返します。 DllMain から LoadLibrary を呼び出すことは安全ではありません。詳細については、 DllMain の「解説」セクションを参照してください。

モジュールハンドルはグローバルでも継承可能でもありません。あるプロセスによる LoadLibrary の呼び出しでは、別のプロセスが使用できるハンドル(たとえば GetProcAddress の呼び出しで使用するもの)は生成されません。他のプロセスは、 GetProcAddress を呼び出す前に、そのモジュールに対して自分自身で LoadLibrary を呼び出す必要があります。

lpFileName がパスを含まず、同じベース名と拡張子を持つロード済みモジュールが複数ある場合、関数は最初にロードされたモジュールへのハンドルを返します。

lpFileName パラメーターにファイル名拡張子が指定されていない場合、既定のライブラリ拡張子 .dll が付加されます。ただし、ファイル名文字列の末尾にピリオド文字(.)を含めることで、モジュール名に拡張子がないことを示すことができます。パスが指定されていない場合、関数は、ロード対象のモジュールのベース名と一致するベース名を持つロード済みモジュールを検索します。名前が一致すれば、ロードは成功します。一致しない場合、関数はファイルを検索します。

最初に検索されるディレクトリは、呼び出し元プロセスの作成に使用されたイメージファイルを含むディレクトリです(詳細については CreateProcess 関数を参照してください)。これにより、プロセスのインストールディレクトリを PATH 環境変数に追加しなくても、そのプロセスに関連付けられたプライベートなダイナミックリンクライブラリ(DLL)ファイルを見つけることができます。相対パスが指定されている場合、相対パス全体が 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 では、その DLL を LoadLibrary を使用して明示的にロードできなくなります。DLL を明示的にロードする場合は、_declspec(thread) の代わりにスレッドローカルストレージ関数を使用する必要があります。例については、 ダイナミックリンクライブラリでのスレッドローカルストレージの使用を参照してください。

セキュリティに関する解説

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

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

Examples

例については、 実行時ダイナミックリンクの使用を参照してください。

メモ

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

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

各言語での呼び出し定義

// KERNEL32.dll  (ANSI / -A)
#include <windows.h>

HMODULE LoadLibraryA(
    LPCSTR lpLibFileName
);
[DllImport("KERNEL32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static extern IntPtr LoadLibraryA(
    [MarshalAs(UnmanagedType.LPStr)] string lpLibFileName   // LPCSTR
);
<DllImport("KERNEL32.dll", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function LoadLibraryA(
    <MarshalAs(UnmanagedType.LPStr)> lpLibFileName As String   ' LPCSTR
) As IntPtr
End Function
' lpLibFileName : LPCSTR
Declare PtrSafe Function LoadLibraryA Lib "kernel32" ( _
    ByVal lpLibFileName As String) As LongPtr
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

LoadLibraryA = ctypes.windll.kernel32.LoadLibraryA
LoadLibraryA.restype = ctypes.c_void_p
LoadLibraryA.argtypes = [
    wintypes.LPCSTR,  # lpLibFileName : LPCSTR
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('KERNEL32.dll')
LoadLibraryA = Fiddle::Function.new(
  lib['LoadLibraryA'],
  [
    Fiddle::TYPE_VOIDP,  # lpLibFileName : LPCSTR
  ],
  Fiddle::TYPE_VOIDP)
#[link(name = "kernel32")]
extern "system" {
    fn LoadLibraryA(
        lpLibFileName: *const u8  // LPCSTR
    ) -> *mut core::ffi::c_void;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("KERNEL32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern IntPtr LoadLibraryA([MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);
"@
$api = Add-Type -MemberDefinition $sig -Name 'KERNEL32_LoadLibraryA' -Namespace Win32 -PassThru
# $api::LoadLibraryA(lpLibFileName)
#uselib "KERNEL32.dll"
#func global LoadLibraryA "LoadLibraryA" sptr
; LoadLibraryA lpLibFileName   ; 戻り値は stat
; lpLibFileName : LPCSTR -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
#uselib "KERNEL32.dll"
#cfunc global LoadLibraryA "LoadLibraryA" str
; res = LoadLibraryA(lpLibFileName)
; lpLibFileName : LPCSTR -> "str"
; HMODULE LoadLibraryA(LPCSTR lpLibFileName)
#uselib "KERNEL32.dll"
#cfunc global LoadLibraryA "LoadLibraryA" str
; res = LoadLibraryA(lpLibFileName)
; lpLibFileName : LPCSTR -> "str"
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	kernel32 = windows.NewLazySystemDLL("KERNEL32.dll")
	procLoadLibraryA = kernel32.NewProc("LoadLibraryA")
)

// lpLibFileName (LPCSTR)
r1, _, err := procLoadLibraryA.Call(
	uintptr(unsafe.Pointer(windows.BytePtrFromString(lpLibFileName))),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // HMODULE
function LoadLibraryA(
  lpLibFileName: PAnsiChar   // LPCSTR
): THandle; stdcall;
  external 'KERNEL32.dll' name 'LoadLibraryA';
result := DllCall("KERNEL32\LoadLibraryA"
    , "AStr", lpLibFileName   ; LPCSTR
    , "Ptr")   ; return: HMODULE
●LoadLibraryA(lpLibFileName) = DLL("KERNEL32.dll", "void* LoadLibraryA(char*)")
# 呼び出し: LoadLibraryA(lpLibFileName)
# lpLibFileName : LPCSTR -> "char*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "kernel32" fn LoadLibraryA(
    lpLibFileName: [*c]const u8 // LPCSTR
) callconv(std.os.windows.WINAPI) ?*anyopaque;
proc LoadLibraryA(
    lpLibFileName: cstring  # LPCSTR
): pointer {.importc: "LoadLibraryA", stdcall, dynlib: "KERNEL32.dll".}
pragma(lib, "kernel32");
extern(Windows)
void* LoadLibraryA(
    const(char)* lpLibFileName   // LPCSTR
);
ccall((:LoadLibraryA, "KERNEL32.dll"), stdcall, Ptr{Cvoid},
      (Cstring,),
      lpLibFileName)
# lpLibFileName : LPCSTR -> Cstring
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
void* LoadLibraryA(
    const char* lpLibFileName);
]]
local kernel32 = ffi.load("kernel32")
-- kernel32.LoadLibraryA(lpLibFileName)
-- lpLibFileName : LPCSTR
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('KERNEL32.dll');
const LoadLibraryA = lib.func('__stdcall', 'LoadLibraryA', 'void *', ['str']);
// LoadLibraryA(lpLibFileName)
// lpLibFileName : LPCSTR -> 'str'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("KERNEL32.dll", {
  LoadLibraryA: { parameters: ["buffer"], result: "pointer" },
});
// lib.symbols.LoadLibraryA(lpLibFileName)
// lpLibFileName : LPCSTR -> "buffer"
// 文字列は "buffer"。ANSI(-A) は new TextEncoder() で UTF-8/ANSI バイト列(末尾に \x00)を渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
void* LoadLibraryA(
    const char* lpLibFileName);
C, "KERNEL32.dll");
// $ffi->LoadLibraryA(lpLibFileName);
// lpLibFileName : LPCSTR
// 構造体/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.ASCII_OPTIONS);
    Pointer LoadLibraryA(
        String lpLibFileName   // LPCSTR
    );
}
@[Link("kernel32")]
lib LibKERNEL32
  fun LoadLibraryA = LoadLibraryA(
    lpLibFileName : UInt8*   # LPCSTR
  ) : Void*
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef LoadLibraryANative = Pointer<Void> Function(Pointer<Utf8>);
typedef LoadLibraryADart = Pointer<Void> Function(Pointer<Utf8>);
final LoadLibraryA = DynamicLibrary.open('KERNEL32.dll')
    .lookupFunction<LoadLibraryANative, LoadLibraryADart>('LoadLibraryA');
// lpLibFileName : LPCSTR -> Pointer<Utf8>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function LoadLibraryA(
  lpLibFileName: PAnsiChar   // LPCSTR
): THandle; stdcall;
  external 'KERNEL32.dll' name 'LoadLibraryA';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "LoadLibraryA"
  c_LoadLibraryA :: CString -> IO (Ptr ())
-- lpLibFileName : LPCSTR -> CString
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let loadlibrarya =
  foreign "LoadLibraryA"
    (string @-> returning (ptr void))
(* lpLibFileName : LPCSTR -> string *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library kernel32 (t "KERNEL32.dll"))
(cffi:use-foreign-library kernel32)

(cffi:defcfun ("LoadLibraryA" load-library-a :convention :stdcall) :pointer
  (lp-lib-file-name :string))   ; LPCSTR
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $LoadLibraryA = Win32::API::More->new('KERNEL32',
    'HANDLE LoadLibraryA(LPCSTR lpLibFileName)');
# my $ret = $LoadLibraryA->Call($lpLibFileName);
# lpLibFileName : LPCSTR -> LPCSTR
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

文字セット違い
類似 API
公式の関連項目