皮皮网
皮皮网

【Dnf多段伤害源码】【用户邮件订阅源码】【信用分系统源码】linux dlopen 源码

来源:9e源码 发表时间:2024-12-29 02:01:23

1.linux的.ko与.so文件
2.一种简单加载vulkan动态库的方法
3.Linux c调用so
4.动态链接库查找路径全面解析,与undefined symbol说再见
5.Linux下通过execl启动另一个程序,如何加载动态库?

linux dlopen 源码

linux的.ko与.so文件

       在Linux系统中,.ko文件代表内核对象文件(Kernel Object),它是将内核功能移动至内核之外,需要时插入内核,Dnf多段伤害源码不需要时卸载的一种方式。这种设计有两大优势:一是可以减小内核体积,二是使用方便。加载内核模块可通过两种方法实现:直接使用insmod命令执行加载操作,或先将模块拷贝至特定目录(基于内核版本的/lib/module/#uname-r#/),接着运行depmod生成依赖关系文件,最后调用modprobe进行加载。加载驱动模块后,通过lsmod命令查看已加载模块列表,用户邮件订阅源码使用rmmod命令卸载。与.so文件相比,.ko文件专门用于内核扩展功能。

       .so文件则与C语言的动态链接库(Dynamic Link Library)相关联。在C语言编程中,动态库调用有两种主要方式:一种类似静态库调用,即通过头文件直接调用库中函数,程序启动时加载库文件;另一种则是通过dlopen和dlsym函数动态加载库,无需直接调用头文件,程序执行到指定位置时加载库文件。这种方式下,不需要在编译时指定库文件位置和名称,但在代码中需使用dlopen加载库,并使用dlsym根据符号查找函数地址。信用分系统源码这两种方式各有优势,可根据项目需求灵活选择。

一种简单加载vulkan动态库的方法

       在适配国产Linux环境的vulkan应用时,常需面对系统自带libvulkan.so.1但缺失libvulkan.so的困境。若系统源缺少vulkan SDK或loader,需手工下载并编译,步骤繁琐且涉及依赖安装与CMake升级。为简化流程,实现快速测试vulkan兼容性和调试应用,本文提出一种简易加载vulkan动态库的方法,无需安装vulkan SDK或loader,直接利用系统中自带的libvulkan.so.1。

       基本原理在于初始化阶段,通过dlopen和dlsym加载vulkan动态库中的入职有赏源码api函数指针,应用程序直接调用这些api。本文采用了一个开源的动态库加载工具dylib,支持多系统平台。以vkCreateInstance函数地址的加载为例,需注意vkCreateInstance在vulkan_core.h中的声明被宏VK_NO_PROTOTYPES括起。在CMake中添加该宏定义(add_definitions(-DVK_NO_PROTOTYPES)),阻止vulkan_core.h对原生vk api进行声明。这样,可在load.h中对原生vulkan api进行声明,实现动态库加载。

       整个load.h源码示例如下,应用于app初始化时调用vk_loader_init(),实现vulkan动态库中所有函数地址的加载。测试demo项目的mfc游戏源码平台地址提供于此。

Linux c调用so

       å®žä¾‹ä»£ç ï¼ˆsoTest.c):

       1 #include <stdio.h>

        2 #include <dlfcn.h>

        3

        4 int main(int argc, char *argv[]){

        5 void * libm_handle = NULL;

        6 float (*cosf_method)(float);

        7 char *errorInfo;

        8 float result;

        9

        // dlopen 函数还会自动解析共享库中的依赖项。这样,如果您打开了一个依赖于其他共享库的对象,它就会自动加载它们。

        // 函数返回一个句柄,该句柄用于后续的 API 调用

        libm_handle = dlopen("libm.so", RTLD_LAZY );

        // 如果返回 NULL 句柄,表示无法找到对象文件,过程结束。否则的话,将会得到对象的一个句柄,可以进一步询问对象

        if (!libm_handle){

        // 如果返回 NULL 句柄,通过dlerror方法可以取得无法访问对象的原因

        printf("Open Error:%s.\n",dlerror());

        return 0;

        }

       

        // 使用 dlsym 函数,尝试解析新打开的对象文件中的符号。您将会得到一个有效的指向该符号的指针,或者是得到一个 NULL 并返回一个错误

        cosf_method = dlsym(libm_handle,"cosf");

        errorInfo = dlerror();// 调用dlerror方法,返回错误信息的同时,内存中的错误信息被清空

        if (errorInfo != NULL){

        printf("Dlsym Error:%s.\n",errorInfo);

        return 0;

        }

       

        // 执行“cosf”方法

        result = (*cosf_method)(0.0);

        printf("result = %f.\n",result);

       

        // 调用 ELF 对象中的目标函数后,通过调用 dlclose 来关闭对它的访问

        dlclose(libm_handle);

       

        return 0;

        }

       åœ¨è¿™ä¸ªä¾‹å­ä¸­ä¸»è¦æ˜¯è°ƒç”¨äº† math 库(libm.so)中的“cosf”函数,dlopen函数的第二个参数表示加载库文件的模式,主要有两种:RTLD_LAZY 暂缓决定,等有需要时再解出符号;RTLD_NOW 立即决定,返回前解除所有未决定的符号。另外记得引用包含API的头文件“#include <dlfcn.h>”(^_^)。

动态链接库查找路径全面解析,与undefined symbol说再见

       在编译、运行大型项目时,"undefined symbol"报错是最常见且棘手的问题。这类问题涉及调整多种环境变量和配置文件,如LD_LIBRARY_PATH、LDFLAGS、LIBRARY_PATH、ldconfig等。大型项目编译耗时,调整环境配置仿佛在无尽等待中徘徊,希望某次调整能成功编译。

       本文以GNU linker(Linux的ld命令)为例,深入解析动态链接库查找路径的细节,并针对编译与运行场景,提供SEARCH_DIR和/etc/ld.so.cache的解决方案。

       在编译过程,动态链接库用于构建程序,ld命令通过链接库找到目标库文件。例如,使用`ld -lcudart`时,需要libcudart.so存在。确保链接器能找到此文件的关键在于指定路径,如`ld -L/path1 -lcudart`。通过`ld -L/path1 -lcudart --verbose`命令查看详细过程,主要关注包含SEARCH_DIR的预定义路径和链接器尝试查找的过程。

       链接器查找动态链接库路径的详细信息可参考Linux官方网站,该网站提供ld的权威信息。此外,理解LDFLAGS、LIBRARY_PATH和LD_LIBRARY_PATH等环境变量对链接器的影响也是关键。LDFLAGS由项目开发者传递给编译器,LIBRARY_PATH由编译器传递给链接器,而LD_LIBRARY_PATH对动态库查找影响较小。

       在编译阶段,链接器预定义的查找路径是固定且不可配置的,如果项目配置不当,即使调整了环境变量,仍可能遇到问题。若多次尝试无果,考虑将要找的libxxx.so路径软链接到链接器预定义路径中。这样,无论项目配置如何,链接器最终都会搜索到该路径。

       运行时,动态链接库查找由Linux库函数dlopen负责。若运行时遇到"undefined symbol"问题,调整`LD_LIBRARY_PATH`环境变量即可。若不想频繁定义环境变量,可修改`/etc/ld.so.conf`和`/etc/ld.so.conf.d/`配置文件,并使用`ldconfig`命令更新`/etc/ld.so.cache`。

       总结,LIBRARY_PATH用于控制编译时链接器查找路径,LD_LIBRARY_PATH用于控制运行时查找动态链接库路径。遇到问题时,考虑在编译时将路径软链接到链接器预定义路径,或在运行时更新`/etc/ld.so.cache`。通常情况下,确保配置正确,避免频繁调整,以避免影响其他用户。

       若使用NVIDIA维护的conda版本的cuda开发套件,通过`conda install cuda -c "nvidia/label/cuda-.8.0"`下载全套cuda开发工具,`${ CONDA_PREFIX}/lib/`包含动态链接库,如libcudart.so,`${ CONDA_PREFIX}/bin/`包含可执行文件,如nvcc。确保在使用CUDA版本时,理解其动态链接库的多重符号链接(如libcudart.so、libcudart.so.等),有助于彻底解决"undefined symbol"问题。

       希望本文内容能帮助大家解决"undefined symbol"问题,彻底告别困扰。

Linux下通过execl启动另一个程序,如何加载动态库?

       没看明白问题

       如果是被调程序加载动态库,那是自动的,由主调进程环境变量决定。

       如果是主调程序加载动态库,则需dlopen打开文件,dlsym按符号获取映射地址,也就是函数或全局数据地址。

相关栏目:探索