Dynamic loading

本文介绍了动态加载机制,这是一种允许程序在运行时加载库文件并获取其中函数和变量地址的机制。文章详细阐述了在C/C++及Java中实现动态加载的方法,并提供了不同操作系统下的具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

From Wikipedia, the free encyclopedia

Jump to: navigation, search

Dynamic loading is a mechanism by which a computer program can, at runtime, load a library (or other binary) into memory, retrieve the addresses of functions and variables contained in the library, execute those functions or access those variables, and unload the library from memory. Unlike static linking and delayed loading, this mechanism allows a computer program to startup in the absence of these libraries, to discover available libraries, and to potentially gain additional functionality. [1][2]

Contents

[hide]

[edit] Uses

Dynamic loading is most frequently used in implementing computer plugins [1]. For example, the Apache Web Server's *.dso "dynamic shared object" plugin files are libraries which are loaded at runtime with dynamic loading [3]. Dynamic loading is also used in implementing computer programs where multiple different libraries may supply the requisite functionality and where the user has the option to select which library or libraries to provide.

[edit] In C/C++

Not all systems support dynamic loading. UNIX-like operating systems such as Mac OS X, Linux, and Solaris provide dynamic loading with the C programming language "dl" library. The Windows operating system provides dynamic loading through the Windows API.

[edit] Summary

NameStandard POSIX/UNIX APIMicrosoft Windows API
Header file inclusion#include <dlfcn.h>#include <windows.h>
Definitions for headerdl

(libdl.so, libdl.dylib, etc. depending on the OS)

Kernel32.dll
Loading the librarydlopenLoadLibrary
LoadLibraryEx
Extracting contentsdlsymGetProcAddress
Unloading the librarydlcloseFreeLibrary

[edit] Loading the Library

Loading the library is accomplished with LoadLibrary or LoadLibraryEx on Windows and with dlopen on UNIX-like operating systems. Examples follow:

[edit] Linux
void* sdl_library = dlopen("libsdl.so", RTLD_LAZY);
if(sdl_library == NULL) {
   // report error ...
} else {
   // use the result in a call to dlsym
}

[edit] Mac OS X

As a UNIX library:

void* sdl_library = dlopen("libsdl.dylib", RTLD_LAZY);
if(sdl_library == NULL) {
   // report error ...
} else {
   // use the result in a call to dlsym
}

As an OS X Framework:

void* sdl_library = dlopen("/Library/Frameworks/SDL.framework/SDL", RTLD_LAZY);
if(sdl_library == NULL) {
   // report error ...
} else {
   // use the result in a call to dlsym
}

[edit] Windows
HMODULE sdl_library = LoadLibrary("SDL.dll");
if( sdl_library == NULL) {
   // report error ...
} else {
   // use the result in a call to GetProcAddress
}

[edit] Extracting Library Contents

Extracting the contents of a dynamically loaded library is achieved with GetProcAddress on Windows and with dlsym on UNIX-like operating systems.

[edit] UNIX/BSD-like Operating Systems (Linux, Mac OS X, Solaris, etc.)
void* initializer = dlsym(sdl_library,"SDL_Init");
if(initializer == NULL) {
   // report error ...
} else {
   // cast initializer to its proper type and use
}

[edit] Windows
void* initializer = GetProcAddress(sdl_library,"SDL_Init");
if(initializer == NULL) {
   // report error ...
} else {
   // cast initializer to its proper type and use
}

[edit] Converting Extracted Library Contents

The C++ programming language prohibits conversion between type void* and a pointer to a function. The following code snippet demonstrates a workaround which allows for this conversion:

typedef void (*sdl_init_function_type)(void);
sdl_init_function_type init_func = *((sdl_init_function_type*)(&initializer));

The above snippet will give a warning on some compilers with a warning: dereferencing type-punned pointer will break strict-aliasing rules. A better workaround on those systems is:

typedef void (*sdl_init_function_type)(void);
union { sdl_init_function_type func; void * obj; } alias;
alias.obj = initializer;
sdl_init_function_type init_func = alias.func;

This makes use of the fact that reading from a different union member than the one most recently written to (called "type-punning") is common, and explictly allowed even if strict aliasing is in force, provided the memory is accessed through the union type directly[4].

[edit] Unloading the Library

Loading a library causes memory to be allocated; the library must be deallocated in order to avoid a memory leak. Additionally, failure to unload a library can prevent filesystem operations on the file which contains the library. Unloading the library is accomplished with FreeLibrary on Windows and with dlclose on UNIX-like operating systems.

[edit] UNIX/BSD-like Operating Systems (Linux, Mac OS X, Solaris, etc.)
dlclose(sdl_library);

[edit] Windows
FreeLibrary(sdl_library);

[edit] Special Library

Both Windows and UNIX implementations of dynamic loading allow programmers to extract symbols from the currently executing process. In both of these APIs, the currently executing process can be "loaded" such that the result can be used in the same manner as the result from dynamically loading a library with LoadLibrary or dlopen.

[edit] UNIX/BSD-like Operating Systems (Linux, Mac OS X, Solaris, etc.)
void* this_process = dlopen(0,0);

[edit] Windows
HMODULE this_process;
GetModuleHandleEx(0,0,&this_process);

[edit] In Java

In the Java programming language, classes can be dynamically loaded using the ClassLoader object. For example:

Class type = ClassLoader.getSystemClassLoader().loadClass(name);
Object obj = type.newInstance();

 

 

http://en.wikipedia.org/wiki/Dynamic_loading

切片过程 1)开始切片过程,在Unity编辑器顶部选择地形选项,然后单击“切片地形”选项。一个窗口会出现一些配置信息。 2)拖动您希望分割为“地形切片”字段的地形。或者,如果您在步骤1中单击“切片地形”选项时选择了地形,则该字段中已经出现了地形。 3)输入每个补丁的详细分辨率。优选地,该值应与每个补丁值的基本地形细节分辨率匹配。这些信息不能通过脚本访问,这就是为什么你必须在这里输入它。您可以输入与基础地形设置不同的值,但这将导致细节网格(植物和草地)复制的准确性降低。 4)选择您希望结束的切片维度。2×2仅仅意味着基本地形将沿着X轴2次和Z轴2次分割,以创建4个地形片。64×64未经测试,不建议使用,所以请自行承担风险。 5)设置希望存储地形数据的文件路径。默认情况下,这是资产/ terrainslicing /地形数据。如果您希望暂时在另一个文件夹中创建地形数据,只需在这里输入新路径。如果希望永久更改默认文件夹,请输入新的文件路径,并选择“保存当前文件路径作为默认文件路径”按钮。请确保没有“/”后的文件路径上的文件夹名称(例如,用于文件的默认路径的地形数据后),否则将会出现错误。 6)当单击“创建地形”按钮时,选择是否覆盖现有的地形数据。这是一个安全功能,以确保你不小心覆盖的地形数据,你已经创造了。如果试图在未选中此值时重写数据,则会出现警告消息,告诉您要检查此值,而切片操作将不会开始。 7)单击“创建地形”按钮,等待进度条填充。如果进度条未显示,则在编辑器窗口显示通知错误的通知消息。有时您可能需要检查控制台以获得更详细的信息。最后,确保只在编辑模式下执行切片地形脚本。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值