当前位置: 首页 > wzjs >正文

设计师招聘网站网站 dns 解析 手机访问设置

设计师招聘网站,网站 dns 解析 手机访问设置,重点实验室网站建设方案,推荐网站建设推广动态库(Dynamic Library)是包含可以由多个程序同时使用的代码和数据的文件。在Windows上,它们通常被称为DLL(动态链接库),而在Linux和macOS上,它们通常被称为共享对象(.so文件&#…

动态库(Dynamic Library)是包含可以由多个程序同时使用的代码和数据的文件。在Windows上,它们通常被称为DLL(动态链接库),而在Linux和macOS上,它们通常被称为共享对象(.so文件)。当程序使用动态库时,有两种主要的调用方式:静态调用(也称为隐式链接)和动态调用(也称为显式链接)。此外,还有一种与动态调用相关的特性叫做延迟加载。

静态调用(隐式链接)

在静态调用中,编译器和链接器会处理库的引用。需要在编译时告诉链接器我们想要使用哪些库,通常通过命令行参数或IDE设置。对于Windows平台上的DLL,这通常意味着添加对.lib文件的引用;对于Linux/macOS平台上的共享对象,则是直接链接.so文件。

Windows 示例 (C++)

假设我们有一个名为mydll.dll的动态库,其中定义了一个函数int add(int a, int b)。为了在程序中使用这个函数,我们需要一个相应的导入库mydll.lib。

// main.cpp - 使用静态调用方式// 假设 we have an import library mydll.lib for mydll.dll
#pragma comment(lib, "mydll.lib") // 告诉链接器需要链接 mydll.libextern "C" int add(int a, int b); // 声明从 DLL 导出的函数int main() {int result = add(5, 3); // 直接调用 DLL 中的函数printf("Result: %d\n", result);return 0;
}

Linux/macOS 示例 ©

在Linux或macOS上,如果我们有一个名为libmydll.so的共享库,我们可以这样链接并调用它:

// main.c - 使用静态调用方式#include <stdio.h>// 假定 libmydll.so 提供了 add 函数
extern int add(int a, int b);int main() {int result = add(5, 3); // 直接调用共享库中的函数printf("Result: %d\n", result);return 0;
}// 编译时需要链接共享库
// gcc main.c -o main -L. -lmydll

动态调用(显式链接)

在动态调用中,我们会在运行时手动加载库,并获取库中函数的地址。下面是如何在不同平台上执行此操作的示例。

Windows 示例 (C++)

// main.cpp - 使用动态调用方式#include <windows.h>
#include <iostream>typedef int (*AddFunc)(int, int);int main() {HMODULE hModule = LoadLibrary(L"mydll.dll"); // 加载 DLLif (!hModule) {std::cerr << "Failed to load DLL" << std::endl;return 1;}AddFunc add = (AddFunc)GetProcAddress(hModule, "add"); // 获取函数指针if (!add) {FreeLibrary(hModule);std::cerr << "Failed to get function address" << std::endl;return 1;}int result = add(5, 3); // 通过函数指针调用std::cout << "Result: " << result << std::endl;FreeLibrary(hModule); // 卸载 DLLreturn 0;
}

Linux/macOS 示例 ©

// main.c - 使用动态调用方式#include <dlfcn.h>
#include <stdio.h>typedef int (*AddFunc)(int, int);int main() {void *handle = dlopen("./libmydll.so", RTLD_LAZY); // 加载共享库if (!handle) {fprintf(stderr, "%s\n", dlerror());return 1;}AddFunc add = (AddFunc)dlsym(handle, "add"); // 获取函数指针const char *dlsym_error = dlerror();if (dlsym_error) {fprintf(stderr, "%s\n", dlsym_error);dlclose(handle);return 1;}int result = add(5, 3); // 通过函数指针调用printf("Result: %d\n", result);dlclose(handle); // 卸载共享库return 0;
}

延迟加载

延迟加载是一种特殊的动态库加载机制,它结合了静态调用的简单性和动态调用的灵活性,延迟加载允许我们在首次调用函数时才加载库,而不是在程序启动时就加载。这可以提高启动速度,并减少内存占用。在Windows上,可以通过链接器选项/DELAYLOAD来实现。在Linux上,可以通过RTLD_LAZY标志来实现。

Windows 示例 (C++)

// main.cpp - 使用延迟加载#pragma comment(linker, "/DELAYLOAD:mydll.dll") // 延迟加载 DLL
#pragma comment(lib, "delayimp.lib") // 需要链接 delayimp.libextern "C" int __declspec(dllimport) add(int a, int b); // 声明从 DLL 导出的函数int main() {int result = add(5, 3); // 第一次调用时加载 DLLprintf("Result: %d\n", result);return 0;
}

在上面的代码中,/DELAYLOAD:mydll.dll指令告诉链接器不要在程序启动时加载mydll.dll,而是等到第一次调用add函数时再加载它。delayimp.lib是一个特殊的库,它提供了必要的支持以实现延迟加载。

Linux/macOS

使用 dlopen 和 RTLD_LAZY

这是最直接的方法,通过显式链接(动态调用)来实现延迟加载。你可以使用 dlopen 函数并传递 RTLD_LAZY 标志来加载库。这种方式允许你在运行时根据条件选择性地加载库,并且符号解析会在首次引用时进行。

void *handle = dlopen("libexample.so", RTLD_LAZY);
if (!handle) {fprintf(stderr, "%s\n", dlerror());exit(EXIT_FAILURE);
}

编译器和链接器支持的延迟加载

一些编译器和链接器提供了内置的支持来实现延迟加载。例如,GNU 编译器集合 (GCC) 和 GNU 链接器 (ld) 提供了 -Wl,–no-as-needed 和 -Wl,-z,lazy 选项来控制库的加载行为。

-Wl,–no-as-needed:确保所有指定的库都被包含在最终的二进制文件中,即使它们没有被直接引用。

-Wl,-z,lazy:告诉链接器以延迟方式加载符号,即符号解析将在首次引用时进行,而不是在加载时立即解析。

你可以在编译和链接时使用这些选项,例如:

gcc -o myprogram myprogram.o -Wl,--no-as-needed -Wl,-z,lazy -lexample

使用 -Wl,–as-needed 和 -Wl,–unresolved-symbols=ignore-all

另一种方法是结合使用 -Wl,–as-needed 和 -Wl,–unresolved-symbols=ignore-all 选项。–as-needed 确保只有在真正需要的时候才加载库,而 --unresolved-symbols=ignore-all 允许链接器忽略未解析的符号,直到它们在运行时被引用。

gcc -o myprogram myprogram.o -Wl,--as-needed -Wl,--unresolved-symbols=ignore-all -lexample

动态链接器配置

Linux 的动态链接器(如 ld.so 或 ld-linux.so)也提供了一些环境变量来控制库的加载行为:

LD_BIND_NOW:如果设置为非空值,强制所有符号在加载时立即解析,相当于 RTLD_NOW。

LD_BIND_LAZY:如果设置为非空值,使符号解析延迟到首次引用时,相当于 RTLD_LAZY。

可以通过设置这些环境变量来影响整个系统的库加载行为,或者仅对特定的应用程序生效:

export LD_BIND_NOW=1  # 强制立即解析所有符号
export LD_BIND_LAZY=1 # 延迟解析符号

总结

静态调用

优点:

简单易用,不需要额外的代码来加载或卸载库。

函数调用更高效,因为地址在程序启动时就已经确定了。

缺点:

如果库不存在或版本不兼容,程序可能无法启动。

即使程序运行时不使用某些库功能,这些库也会被加载到内存中。

动态调用

优点:

可以根据条件选择性地加载库,节省资源。

可以更容易地支持插件架构或多版本库共存。

缺点:

代码更加复杂,需要管理库的加载、卸载和错误处理。

每次调用库函数时都需要通过指针进行间接调用,这可能会稍微降低性能。

延迟加载

优点

提高了程序的启动速度,因为不必要的库不会在启动时加载。

减少了内存占用,只有实际需要的库才会被加载。

缺点

如果库加载失败,错误可能会在程序运行过程中出现,而不是在启动时。

一些平台或编译器可能不支持延迟加载,或者需要特定的编译选项来启用。


文章转载自:

http://sd1G7g6E.wdpbq.cn
http://aGY3CvB0.wdpbq.cn
http://deIVPanS.wdpbq.cn
http://YFPINoc7.wdpbq.cn
http://U5Rsx099.wdpbq.cn
http://pTd7MCyz.wdpbq.cn
http://31HERfVi.wdpbq.cn
http://KCYukEWS.wdpbq.cn
http://0aNcbw8K.wdpbq.cn
http://jADGLely.wdpbq.cn
http://YvRkHJaY.wdpbq.cn
http://m9D5qusV.wdpbq.cn
http://SfikZOjZ.wdpbq.cn
http://4hNzqpon.wdpbq.cn
http://2iXr1UAY.wdpbq.cn
http://y2rR4fhm.wdpbq.cn
http://FFEJh3Nj.wdpbq.cn
http://S13UGSBX.wdpbq.cn
http://bj5mpdV5.wdpbq.cn
http://9NMl82px.wdpbq.cn
http://22lvsSny.wdpbq.cn
http://bn7jUUji.wdpbq.cn
http://VvNM4her.wdpbq.cn
http://XmVYTNpi.wdpbq.cn
http://FRnwrGl4.wdpbq.cn
http://2ZlsMeEI.wdpbq.cn
http://5J44EdaR.wdpbq.cn
http://ppqUDtuk.wdpbq.cn
http://SEBDobHZ.wdpbq.cn
http://UJMAOn1L.wdpbq.cn
http://www.dtcms.com/wzjs/713585.html

相关文章:

  • 做电商网站都需要学什么软件四川建筑职业技术学院教务网
  • 会展中心网站建设奉化网站建设怎么样
  • wordpress 大型网站我自己做个网站怎么做
  • 贺兰县住房城乡建设局网站网站建设服务合同是否缴纳印花税
  • 大气蓝色企业网站模板南京外包公司
  • 可做百度百科参考资料的网站做网站最简单的工具
  • 网站备案ip地址wordpress访问文件夹
  • spark怎么做网站数据库如何注册个人营业执照
  • 互联网传媒 网站wordpress如何删除以前主题的缓存
  • 江苏住房建设厅网站注册网站引流
  • 昆山高端网站设计公司软路由做网站
  • 小榄网站建设推广那个网站做的好
  • 首饰网站建设策划案桂林旅游
  • 商城网站网站开发WordPress小程序二次修改
  • 传奇网站怎么做仿模板电影网站
  • 上海网站设计公司 静安线下怎么做推广和宣传
  • 网站做众筹需哪些条件网站用什么框架
  • 哪里可以做网站的wordpress备份和还原
  • 微信红包网站制作企业微信开通流程
  • 做期货看资讯什么网站好湛江网站制作网站
  • 珠宝网站建设方案开源门户网站建设方案
  • 外包网站设计公司dw不用代码做网页
  • 网红自助下单网站史志网站建设必要性
  • 宠物用品网站开发背景个人网站规划书模板
  • 美橙互联网站备案做小程序需要什么技术
  • 公司网站开发费用入哪个科目上海闵行区怎么样
  • 北京建行网站东营租房信息网官网
  • 网站开发收费标准做库房推广哪个网站好
  • 橙米网站建设网站标识描述可以填关键词吗
  • 建设个定制网站需要多少钱大数据营销的核心