动态连接库和符号(symbol)

合集下载

大学电路同名端的判定方法

大学电路同名端的判定方法

大学电路同名端的判定方法大学电路中,同名端的判定方法可以通过以下几种方式来进行:1. 端口标注法(Port labeling method):这是最常用的一种判定方法。

在大多数电路图中,每个元件的端口都会被标注上符号,如V、A、B等。

当两个元件的端口标注相同时,即可判定它们为同名端。

例如,当电路图中一个电压源的正极被标注为V,而一个电阻的一端也被标注为V时,就可以认为它们是同名端。

这种方法简单明了,容易理解和操作。

2. 连接关系法(Connection method):这种方法主要适用于复杂的电路图,通过观察元件之间的连接关系来判定同名端。

当两个元件的一个端口与其他元件相连接时,它们很有可能是同名端。

例如,当一个电压源的正极与一个电阻相连接时,可以认为它们是同名端。

对于复杂的电路图,可以借助连线颜色、虚线等手段来帮助观察连接关系。

3. 符号法(Symbol method):这种方法主要适用于线路较为简单的情况,通过观察元件符号的形状和特点来判定同名端。

在大多数电路图中,元件的符号形状是经过标准化的,符号之间存在一定的相似性。

当两个元件的符号之间存在相似性时,即可判定它们为同名端。

例如,在一个电路图中,一个电力源的符号上有两个平行的线段,而一个电压表的符号上也有两个平行的线段,那么可以认为它们是同名端。

4. 连接状态法(Connection status method):这种方法主要适用于已经搭建好的电路实验中,通过测量电路的具体参数来判定同名端。

当两个元件的连接状态相同时,即可判定它们为同名端。

例如,在一个电路实验中,当两个电阻的一端接在同一个节点上,并且测得的电阻值相等时,可以认为它们是同名端。

总之,判定大学电路中同名端的方法主要包括端口标注法、连接关系法、符号法和连接状态法。

不同的方法可以互相补充,根据具体的情况选择合适的方法进行判定。

对于复杂的电路图,可以通过结合多种判定方法来提高准确性。

dlopen、dlsym和dlclose的使用和举例

dlopen、dlsym和dlclose的使用和举例

dlopen、dlsym和dlclose的使用和举例之前用过这三个函数一直没时间整理一下。

今天抽时间整理一下。

1、函数简介dlopen基本定义功能:打开一个动态链接库包含头文件:#include <dlfcn.h>函数定义:void * dlopen( const char * pathname, int mode );函数描述:在dlopen的()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。

使用dlclose()来卸载打开的库。

mode:分为这两种RTLD_LAZY 暂缓决定,等有需要时再解出符号RTLD_NOW 立即决定,返回前解除所有未决定的符号。

RTLD_LOCALRTLD_GLOBAL 允许导出符号RTLD_GROUPRTLD_WORLD返回值:打开错误返回NULL成功,返回库引用编译时候要加入 -ldl (指定dl库)dlsym()功能:根据动态链接库操作句柄与符号,返回符号对应的地址。

包含头文件:#include <dlfcn.h>函数定义:void*dlsym(void* handle,const char* symbol)函数描述:dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的地址。

使用这个函数不但可以获取函数地址,也可以获取变量地址。

handle是由dlopen打开动态链接库后返回的指针,symbol就是要求获取的函数或全局变量的名称。

dlclose()dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

上述都是摘抄,总结为链接的时候需要用到dl库,编译的时候需要加上dlfcn.h头文件。

才能保证编译不会报错。

2、生成动态库hello.c函数原型:#include <sys/types.h>#include <signal.h>#include <stdio.h>#include <unistd.h>typedef struct {const char *module;int (*GetValue)(char *pszVal);int (*PrintfHello)();} hello_ST_API;int GetValue(char *pszVal){int retval = -1;if (pszVal)retval = sprintf(pszVal, "%s", "123456");printf("%s, %d, pszVer = %s\n", __FUNCTION__, __LINE__, pszVal);return retval;}int PrintfHello(){int retval = -1;printf("%s, %d, hello everyone\n", __FUNCTION__, __LINE__);return 0;}const hello_ST_API Hello = {.module = "hello",GetValue,PrintfHello,};编译的时候用指令:gcc -shared -o hello.so hello.c上面的函数是用一个全局结构体hello来指向。

dlsym用法 -回复

dlsym用法 -回复

dlsym用法-回复dlsym用法详解:动态链接库中的函数符号查找一、引言在C和C++语言中,动态链接库(Dynamic Link Library,简称DLL)是一种共享库的形式,其中包含了可被外部应用程序调用的函数、全局变量和其他可执行代码。

调用动态链接库中的函数时,需要根据函数名获取其地址,然后通过该地址来进行调用。

dlsym就是一种在动态链接库中查找符号(函数、变量等)地址的方法。

本文将详细介绍dlsym的用法,并逐步解释其实现过程。

二、dlsym函数介绍在Unix和类Unix系统中,dlsym函数用于在动态链接库中查找符号地址。

其原型定义在dlfcn.h头文件中,如下所示:void *dlsym(void *handle, const char *symbol);其中,handle是已经打开的动态链接库的句柄,而symbol是要查找的符号的名称。

dlsym会通过symbol参数在handle所指向的动态链接库中查找symbol对应的地址,并返回该地址的指针。

三、使用dlsym查找动态链接库中的符号地址1. 打开动态链接库首先,我们需要打开一个动态链接库,获取其句柄。

可以使用dlopen函数来打开动态链接库,如下所示:#include <dlfcn.h>void *handle = dlopen("./test.so", RTLD_LAZY);在这个例子中,我们使用了dlopen函数打开了一个名为test.so的动态链接库,并将返回的句柄保存到handle变量中。

RTLD_LAZY是一个标志参数,表示当需要时才解析符号引用。

2. 查找符号地址有了动态链接库的句柄之后,我们可以使用dlsym函数来查找符号的地址。

如下所示:#include <dlfcn.h>void *symbol_ptr = dlsym(handle, "symbol_name");在这个例子中,我们通过在handle所指向的动态链接库中查找名为symbol_name的符号,并将其地址保存到symbol_ptr指针中。

西方哲学中的“符号”概念

西方哲学中的“符号”概念

西方哲学中的“符号”概念“符号”(symbol)是我们在学术和日常语言中频繁使用的一个外来词。

从西方哲学的意义上说,符号就是意义载体。

例如,十字路口的红绿灯、词语“美丽”、公式“1+1=2”、摇头的动作,它们分别指示着特定的交通规则、语义、数学规律和意愿,无一不承载特定意义,因而都是符号。

如此看来,符号可以是物,是词语,也可以是约定俗成的标记,还可以是姿态。

也可以看到,一般而言,符号总是具体而感性的,而它所代表的则是一般的观念。

符号之所以是符号,恰恰在于它能在自身之内把感性和理性、具体和一般合二为一。

从词源学上说,“符号”可以追溯到古希腊词σμβολον(symbolon),它的意思是:“被扔到一起的东西”。

在古希腊,符号通常是某个经由使者在朋友或生意伙伴间传达的信物或公证物。

人们先把某个东西(如硬币、铭牌)一分为二,让每个使者各执其一。

如果两人重逢时能出示各自的一半、并将它们严丝合缝地嵌合起来的话,就可以按照主人的委托完成一桩生意。

因此在最古老的意义上,符号乃是用以保证生意往来中合同和约定的可信性的“身份证”。

词源学考察也向我们暗示出,符号往往是部分的,而它代表的意义则是整体的。

作为载体的符号具有多种形态,对它所代表的意义的解释也因不同文化领域而异。

事实上,“符号”概念内涵丰富而多有歧义,殊难定义,在哲学上也不例外。

不过为了方便理解,我们可以它被考察的方式,对它做出宏观和微观的区分。

宏观意义上的“符号”概念强调符号的存在性质和样态,它所涉及的主要是符号的判定和分类问题。

符号的判定主要是标准问题,根据不同的标准,符号的范围也就有大有小。

比如,有的符号理论家只把语言文字认作符号,有的则把整个世界看作是由符号所充实的。

这里也牵涉到对“符号”与“记号”(sign)从属关系的看法。

在日常语言中二者可以互换使用,指的都是传情达意的载体。

然而在符号理论家那里则有所不同。

有人把“记号”看作一个总概念,而把符号仅仅看作一种特殊的记号;有的则相反,把“记号”看作一种特殊的符号。

linux elf 符号表

linux elf 符号表

linux elf 符号表摘要:1.引言2.Linux ELF 文件结构概述3.符号表的定义与作用4.符号表的类型5.符号表的编码方式6.符号表的应用示例7.结论正文:1.引言Linux 是一个广泛使用的开源操作系统,其背后的核心技术之一就是ELF (Executable and Linkable Format)可执行和可链接文件格式。

在ELF 文件中,符号表是一个重要的组成部分,它记录了程序中各种符号的信息,如函数名、变量名等。

本文将详细介绍Linux ELF 文件中的符号表。

2.Linux ELF 文件结构概述ELF 文件由三部分组成:ELF 头部(ELF Header)、程序头部表(Program Header Table)和节(Section)。

- ELF 头部:包含了ELF 文件的类型、入口地址等信息。

- 程序头部表:包含了多个程序头部,每个程序头部对应一个ELF 节。

- 节:是ELF 文件中可执行代码和数据的组织单位,包含了代码、数据、符号表等各种信息。

3.符号表的定义与作用符号表是一个数据结构,用于存储程序中各种符号的信息,如函数名、变量名等。

在ELF 文件中,符号表位于某个节(Section)内,通常以".symtab" 或".dynsym" 命名。

符号表的主要作用是:- 为调试器提供符号信息,方便程序员调试程序。

- 作为链接器链接目标文件的依据,确保链接过程中符号的正确解析。

4.符号表的类型符号表有多种类型,根据不同的需求和应用场景,可以选择不同类型的符号表:- 普通符号表(Common Symbol Table):包含了所有可见的符号(即在当前模块中定义的符号和在其他模块中引用的符号)。

- 动态符号表(Dynamic Symbol Table):包含了所有动态加载的符号,如共享库中的符号。

- 弱符号表(Weak Symbol Table):包含了弱符号,即在链接过程中可以被其他符号覆盖的符号。

PowerPC上ELF可执行文件的符号解析(一)

PowerPC上ELF可执行文件的符号解析(一)

PowerPC上ELF可执行文件的符号解析(一)一.前言符号解析是Linux系统导入二进制可执行文件的重要过程,它完成的工作包括将一个符号定位到实际的内存位置,并且要保证可以正确引用这些符号。

按解析对象的不同它可以分为变量符号解析和函数符号解析;按解析方式的不同可以分为静态解析和动态解析。

对于静态解析的符号,它们的位置在文件生成时就由link editor(在Linux下通常是ld)已经确定下来了;对于动态解析的符号,他们的位置在程序运行时才由dynamic linker(动态链接器,32位Linux平台下通常是/lib/ld.so.1)确定下来。

我们可以这么认为,如果一个符号在共享库中定义,那么当其他可执行文件或共享库引用这个符号时,就需要对它作动态解析。

变量符号的动态解析过程比较简单,系统在载入程序过程中将变量symbol位置存入到GOT (Global Offset Table)中,引用变量symbol时首先计算出GOT表的实际位置,然后以它作为基址加上(变量symbol在GOT表中的偏移量)就可以从GOT表中取得该symbol的实际位置。

下面以SUSE Linux Enterprise Server 8.1 for IBM pSeries为例,主要讲述和演示32位PowerPC Linux下函数符号的动态解析过程。

二.概念在讲述解析过程之前,先介绍一下在解析过程中要用到的基本概念。

1.ELF(Executable and Linkable Format)文件ELF是Linux缺省采用的可执行文件(包括共享库,object文件)的格式,具体规范参见参考文献[1]、[2]。

这里需要提一下的是section这个概念:section是ELF文件中一段互相了解信息,它可以是一段数据,也可以是一段代码。

比如可执行代码信息就放在.text section 中,被用户初始化的变量会放在.data section中,没有被用户初始化的变量会放在.bss section(bss是below stack segment的缩写)中。

嵌入式系统程序设计(6章)赖晓晨

嵌入式系统程序设计(6章)赖晓晨

4. 共享库错误函数
函数原型: const char *dlerror(void); 功能描述:当动态链接库操作函数 (dlopen、dlsym、dlclose)执 行失败时,dlerror可以返回出错信息, 返回值为NULL时表示操作函数执行成 功。
【例6-2】
/* ch6_2 sub.h */ #ifndef SUB_H #define SUB_H int square(int); #endif /* ch6_2 sub.c */ #include <stdio.h> int square(int a) { printf("the square of the number is:"); return a*a; }
打开共享库(续)
功能描述:参数中的libname一般是库的绝对路径, 这样dlopen会直接装载该文件;如果只是指定了库名 称,在dlopen会按照下面的机制去搜寻:
根据环境变量LD_LIBRARY_PATH查找; 根据/etc/ld.so.cache查找; 依次在/lib和/usr/lib目录查找。
库分类
静态库,是在执行程序运行前就已经加入到执 行码中,在物理上成为执行程序的一部分。
共享库,是在执行程序启动时加载到执行程序 中,可以被多个执行程序共享使用。 动态链接库,其实并不是一种真正的库类型, 应该是一种库的使用技术,应用程序可以在运 行过程中随时加载和使用库。
库命名约定
所有库都以lib开头,表示一个库文件;
}
handle=dlopen("/lib/libmydll.so", RTLD_LAZY); if(!handle) { printf("%s\n",dlerror()); 如未找到函数,显 } 示error中的错误 fp=dlsym(handle, "square"); 信息 if((error=dlerror())!=NULL) { printf("%s\n",error); dlclose(handle); exit(1); } printf("now call the function square.\n"); result = (*fp)(n); printf(" %d\n",result); dlclose(handle); return 0;

了解动态链接(五)——动态符号表

了解动态链接(五)——动态符号表

了解动态链接(五)——动态符号表ilocker:关注 Android 安全(新⼊⾏,0基础) QQ: 2597294287动态符号表 (.dynsym) ⽤来保存与动态链接相关的导⼊导出符号,不包括模块内部的符号。

⽽ .symtab 则保存所有符号,包括 .dynsym 中的符号。

动态符号表中所包含的符号的符号名保存在动态符号字符串表 .dynstr 中。

使⽤ readelf 查看 .dynsym 表,如:readelf --dyn-syms libstdc++.so。

可以看到,.dynsym 表包含39项。

__cxa_atexit 是⼀个导⼊符号,⽽ __cxa_guard_acquire 则是⼀个导出符号。

搜索 android libstdc++ 库的源码,能找到该导出函数的定义:书上说很多动态链接的模块同时拥有 .dynsym 和 .symtab 两个表,但我查看了 android 下的⼏个系统共享库:libc.so、.liblog.so、libm.so、libstdc++.so,都是只有 .dynsym。

其实按我的理解,so 库中就是只有 .dynsym 就可以了,⽤于动态链接时的符号查找和地址重定位。

.symtab 中的内部符号,此时已经没什么⽤了,所以没必要存在 .symtab。

补充:后来发现,android 5 系统中的 libc 等 so 中是具有 .symtab 和 .strtab 的。

另外,对于⾃⼰使⽤ NDK 开发的 so,在 \libs\armeabi 下的 so 是经过 strip 的(最后被打包到 apk 中的)so,在这个 so 中是没有 .symtab 和 .strtab 的。

但在 \obj\local\armeabi 下,有未经过 strip 处理的 so,他⾥⾯是有 .symtab 和 .strtab 的,默认在⽂件中,位于所有 section 的最后。

在 android 的 linker 进⾏符号重定位⼯作时,⾸先要在符号表中查找符号。

DLD链接命令语言

DLD链接命令语言

DLD链接命令语言Create by zaken 2007-4-11file:///E:/Tornado2.2/docs/diab5.0ppc/c-linkea.htm链接命令语言的作用:1 指定输入文件和选项2 指定如何把输入的段区联合成输出的段区3 指定内存如何配置并且分配输出段区到内存区间4 为符号分配地址或者其他值语法表示法:以下符号是命令的一部分{ } ( ) , ; > *{} 包含在括号内的段比如Mem{ram1: org=0x0000,len=0x10000}() 相当于函数调用比如ADDR(rom), 分隔符; 命令结束符> 相当于向后赋值* 相当于地址符号符号表示法:符号一旦被定义,可以在任意地方使用。

符号在OBJ文件内或者被分配命令定义。

分配命令定义的符号遵循C语言语法,使用$和.来比如$data 或则.data;一个符号或者文件名包含$和.的,必须用双引号包括,比如“a.o”或者“$da.da”表达式:一个链接表达式可以在任意地方使用,遵循以下C语言格式数字符号一元操作表达式二进制操作表达式expression ? expression : expression( expression )一元操作表达式可以使用以下C语言操作符! ~二进制操作表达式可以使用以下C语言操作符* / % + - >> << == != <> <= => & | && ||操作符的优先权符合C语言,使用括号可以改变优先权当符号在表达式中使用时,符号的地址被使用,符号”.”表示当前位置计数(只允许在section 的命令中使用)以下的假函数在在表达式中是有效的SIZEOF(section-name) 段区的大小注意:在段区内使用SIZEOF不是一种可靠的计算下一个段的起始地址的办法,因为对齐会导致ADDR(.text)+SIZEOF(.text)不是下一个段的起始地址,解决的办法如下.text(TEXT):{ *(.text)MYTEXT=.;注意MYTEXT有可能不等于ADDR(.text)+SIZEOF(.text)}>rom1.data(DATA):{.data (DATA) LOAD(MYTEXT):{}}SIZEOF(memory-area-name) 被MEMORY命令定义的内存区大小ADDR(section-name) 段区的地址NEXT(expr)HEADERSZ 标题的大小命令文件结构:一个命令文件由一系列的命令组成,包括:MEMORY{内存区定义}SECTIONS{段区或者组定义}分配命令assignment-command目标文件名存档文件名archive-filename命令行选项注意以上的命令在一个命令文件中可以被多次使用MEMORY命令{内存区定义}MEMORY命令用来一个或者多个内存区,比如“rom”,”ram”。

Linux动态库undefinedsymbol原因定位与解决方法

Linux动态库undefinedsymbol原因定位与解决方法

Linux动态库undefinedsymbol原因定位与解决⽅法在使⽤动态库开发部署时,遇到最多的问题可能就是 undefined symbol 了,导致这个出现这个问题的原因有多种多样,快速找到原因,采⽤对应的⽅法解决是本⽂写作的⽬的。

可能的原因1. 依赖库未找到这是最常见的原因,⼀般是没有指定查找⽬录,或者没有安装到系统查找⽬录⾥2. 链接的依赖库不⼀致编译的时候使⽤了⾼版本,然后不同机器使⽤时链接的却是低版本,低版本可能缺失某些 api3. 符号被隐藏如果动态库编译时被默认隐藏,外部代码使⽤了某个被隐藏的符号。

4. c++ abi 版本不⼀致最典型的例⼦就是 gcc 4.x 到 gcc 5.x 版本之间的问题,在 4.x 编辑的动态库,不能在 5.x 中链接使⽤。

解决⽅法1. 依赖库未找到使⽤ ldd -r , 确定系统库中是否存在所依赖的库执⾏ ldconfig 命令更新 ld 缓存执⾏ ldconfig -p | grep {SO_NAME} 查看是否能找到对应的库检查 LD_LIBRATY_PATH 是否设置了有效的路径2. 链接的库版本不⼀致如果系统中之前有安装过相同的库,或者存在多个库,就需要确定链接的具体是哪个库有⼀个特殊场景需要注意下,.so ⽂件中有个默认 rpath 路径,⽤于搜索被依赖的库,这个路径优先于系统⽬录和LD_LIBRARY_PATH。

假如 rpath 存在相同名字的 .so ⽂件,会优先加载这个路径的⽂件。

在遇到 undefined symbol 问题时,使⽤ readelf -d | grep rpath 查看:$ readelf -d libSXVideoEngineJni.so | grep rpath0x000000000000000f (RPATH) Library rpath:[/home/slayer/workspace/SXVideoEngine-Core/Render/cmake-build-debug:/home/slayer/workspace/SXVideoEngine-Core/Render/../../SXVideoEngine-Core-Lib/blend2d/linux/lib]如果存在的路径中有相应的库,可以先重命名⽂件再测试确认。

Mentor库管理工具(Symbol的制作)

Mentor库管理工具(Symbol的制作)

利用Mentor实现Symbol的制作康讯EDA设计部孟有权 2008年4月【摘要】在制作原理图前,先要制作原理图所要用到的器件的图形符号,Symbol 也就是电路元器件所对应的图形,Symbol是带有PIN的图形符号,Symbol不但有相应的属性,而且不同的Symbol有不同的属性,本文仅仅介绍如何利用Mentor里面的Symbol Editor、Symbol Wizard和DxDesigner这三个工具来制作Symbol,以及在制作Symbol的过程中应该注意的问题。

另外,在运用过程中可能还会有些问题出现,不足之处还需要自己的摸索和探讨。

【关键字】Symbol、Expedition、Wizard、DxDesigner、Partation、Parts、Cells 【正文】在制作原理图前,先要制作原理图所要用到的器件的图形符号,Symbol 也就是电路元器件所对应的图形,用图形来描述一个器件的结构,在画原理图的时候用Symbol表示的是一个器件,但是Symbol并不是简简单单的图形,而是带有PIN的图形符号,Symbol不但有相应的属性,而且不同的Symbol有不同的属性,而且Symbol 所带的PIN根据功能和用途的不同也有不同的属性。

下图就是一些简单的Symbol。

在此仅仅介绍如何利用Library Manager里面的工具来制作Symbol。

图 1注:在这里要说明一点的是,在建库时如果选择的是DX Designer/Expedition,那么在这里所建的Symbol就是上面的那些类型的Symbol,但是如果选择的是Design Capture/Expedition,那么在这里制作的就不是上面类型的Symbol了,但是两者都是可以用来制作原理图的,前者就是下面要制作的原理图,而后者目前只是知道能够用来实现电路的仿真、测试。

下面主要介绍在DX Designer/Expedition类型的库下来制作Symbol。

未解决的外部符号unresolved extern symbol

未解决的外部符号unresolved extern symbol

学习VC++时经常会遇到链接错误LNK2001,该错误非常讨厌,因为对于编程者来说,最好改的错误莫过于编译错误,而一般说来发生连接错误时,编译都已通过。

产生连接错误的原因非常多,尤其LNK2001错误,常常使人不明其所以然。

如果不深入地学习和理解VC++,要想改正连接错误LNK2001非常困难。

初学者在学习VC++的过程中,遇到的LNK2001错误的错误消息主要为:unresolved external symbol “symbol”(不确定的外部“符号”)。

如果连接程序不能在所有的库和目标文件内找到所引用的函数、变量或标签,将产生此错误消息。

一般来说,发生错误的原因有两个:一是所引用的函数、变量不存在、拼写不正确或者使用错误;其次可能使用了不同版本的连接库。

以下是可能产生LNK2001错误的原因:一.由于编码错误导致的LNK2001。

1.不相匹配的程序代码或模块定义(.DEF)文件能导致LNK2001。

例如, 如果在C++源文件内声明了一变量“var1”,却试图在另一文件内以变量“VAR1”访问该变量,将发生该错误。

2.如果使用的内联函数是在.CPP文件内定义的,而不是在头文件内定义将导致LNK2001错误。

3.调用函数时如果所用的参数类型同函数声明时的类型不符将会产生LNK2001。

4.试图从基类的构造函数或析构函数中调用虚拟函数时将会导致LNK2001。

5.要注意函数和变量的可公用性,只有全局变量、函数是可公用的。

静态函数和静态变量具有相同的使用范围限制。

当试图从文件外部访问任何没有在该文件内声明的静态变量时将导致编译错误或LNK2001。

函数内声明的变量(局部变量)只能在该函数的范围内使用。

C++的全局常量只有静态连接性能。

这不同于C,如果试图在C++的多个文件内使用全局变量也会产生LNK2001错误。

一种解决的方法是需要时在头文件中加入该常量的初始化代码,并在.CPP文件中包含该头文件;另一种方法是使用时给该变量赋以常数。

linux dlsym 指针参数

linux dlsym 指针参数

linux dlsym 指针参数dlsym是在Linux系统上动态链接库中查找符号的函数。

它的原型如下:```void *dlsym(void *handle, const char *symbol);```参数说明:- `handle`是一个指向已打开动态链接库的句柄的指针。

- `symbol`是要查找的符号名称的字符串。

返回值:-如果找到符号,返回指向符号的地址的指针。

-如果符号未找到,返回NULL。

在使用dlsym时,一个常见的使用情况是通过动态加载库来检查并调用一些特定的函数或者获取一些符号的值,而不需要在代码中直接链接这些库。

假设我们有一个动态库`libtest.so`,其中包含了一个名为`print_hello`的函数,我们可以使用dlsym来动态地在程序中加载并调用该函数,而无需在编译阶段将其链接到程序。

首先,我们需要使用dlopen来打开我们的动态库,并获取句柄:```cvoid *handle = dlopen("libtest.so", RTLD_LAZY);if (!handle) {fprintf(stderr, "Failed to open library: %s\n",dlerror());return -1;}```上面的代码将会加载名为`libtest.so`的动态库,并将其句柄存储在`handle`变量中。

接下来,我们可以使用dlsym来查找并获取`print_hello`函数的地址:```cvoid (*print_hello)() = dlsym(handle, "print_hello");if (!print_hello) {fprintf(stderr, "Failed to load symbol: %s\n", dlerror());dlclose(handle);return -1;}```上面的代码定义了一个函数指针`print_hello`,然后使用dlsym来查找并将`print_hello`函数的地址赋值给该指针。

链接时出现错误 error LNK2001 无法解析的外部符号

链接时出现错误 error LNK2001 无法解析的外部符号
5.当编译调试版的应用程序时,如果采用发行版模态库进行连接也会产
生LNK2001;同样,使用调试版模态库连接发行版应用程序时也会产生相同的
问题。
6.不同版本的库和编译器的混合使用也能产生问题,因为新版的库里可
能包含早先的版本没有的符号和说明。
7.在不同的模块使用内联和非内联的编译选项能够导致LNK2001。如果
二.由于编译和链接的设置而造成的LNK2001
1.如果编译时使用的是/NOD(/NODEFAULTLIB)选项,程序所需要的运行
库和MFC库在连接时由编译器写入目标文件模块, 但除非在文件中明确包含
这些库名,否则这些库不会被链接进工程文件。在这种情况下使用/NOD将导
致错误LNK2001。
2.如果没有为wWinMainCRTStartup设定程序入口,在使用Unicode和MFC
时将得到“unresolved external on _WinMain@16”的LNK2001错误信息。
3.使用/MD选项编译时,既然所有的运行库都被保留在动态链接库之内,
源文件中对“func”的引用,在目标文件里即对“__imp__func” 的引用。
如果在C++ 源文件内声明了一变量“var1”,却试图在另一文件内以变量 再在stdafx.cpp中定义CDatabase db就可以了
“VAR1”访问该变量,将发生该错误。
2.如果使用的内联函数是在.CPP文件内定义的,而不是在头文件内定
义将导致LNK2001错误。
3.调用函数时如果所用的参数类型同函数声明时的类型不符将会产生
如果试图使用静态库LIBC.LIB或LIBCMT.LIB进行连接,将在__imp__func上发

数据库连接符号

数据库连接符号

数据库连接符号数据库连接符号是指在数据库系统中用于建立连接和执行操作的特定符号或字符串。

数据库连接符号的选择和使用对于正确连接数据库以及执行操作非常重要。

常见的数据库连接符号包括:1. JDBC连接符号:JDBC(Java Database Connectivity)是Java语言访问数据库的标准接口,它定义了一套用于Java程序与各种关系型数据库进行连接和交互的API。

在JDBC中,数据库连接符号通常以类似于"jdbc:数据库类型://主机名:端口号/数据库名"的格式来表示。

其中,"jdbc"是JDBC的协议标识,数据库类型可以是MySQL、Oracle、SQL Server等,主机名和端口号表示数据库服务器的地址和端口号,数据库名表示所要连接的数据库的名称。

2. ODBC连接符号:ODBC(Open Database Connectivity)是一种用于实现数据库的标准接口,它允许应用程序以统一的方式访问不同类型的数据库。

在ODBC中,数据库连接符号通常以类似于"DRIVER={驱动程序名};SERVER=服务器名;DATABASE=数据库名"的格式来表示。

其中,驱动程序名是指与数据库对应的ODBC驱动程序的名称,服务器名表示数据库服务器的地址,数据库名表示所要连接的数据库的名称。

3. URL连接符号:URL(Uniform Resource Locator)是用于定位和访问Internet上资源的统一资源定位符。

在数据库中,URL连接符号通常以类似于"jdbc:数据库类型://主机名:端口号/数据库名?参数"的格式来表示。

其中,数据库类型、主机名、端口号、数据库名的含义与JDBC连接符号相同,而参数用于指定一些连接的附加信息,例如用户名、密码等。

无论使用何种数据库连接符号,都需要确保符号的准确性和完整性,以确保正确连接数据库并执行操作。

动态链接库(dll)学习资料总结

动态链接库(dll)学习资料总结

1. 什么是lib文件,lib和dll的关系如何(1)lib是编译时需要的,dll是运行时需要的。

如果要完成源代码的编译,有lib就够了。

如果也使动态连接的程序运行起来,有dll就够了。

在开发和调试阶段,当然最好都有。

(2)一般的动态库程序有lib文件和dll文件。

lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的。

如果有dll文件,那么对应的lib文件一般是一些索引信息,具体的实现在dll文件中。

如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。

静态编译的lib文件有好处:给用户安装时就不需要再挂动态库了。

但也有缺点,就是导致应用程序比较大,而且失去了动态库的灵活性,在版本升级时,同时要发布新的应用程序才行。

(3)在动态库的情况下,有两个文件,一个是引入库(.LIB)文件,一个是DLL文件,引入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,DLL 库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行时再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。

从上面的说明可以看出,DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。

2、严重警告:(1) 用 extern "C" _declspec(dllexport) 只可以导出全局函数,不能导出类的成员函数(2) 使用extern "C" _declspec(dllexport)输出的函数可以被c语言调用,否则则不可(3) 注意标准调用约定的问题,输出与调用的函数约定应该一致,如当dll 模块的函数输出采用标准调用约定_stdcall,则调用程序的导入函数说明也要用标准约定(4) 用extern "C" _declspec(dllexport) 和 EXPOTRT导出的函数不改变函数名,可以给c++或c编写的exe调用.假如没有extern "C",导出的函数名将会改变,只能给c++编写的exe调用(5)在动态加载动态链接库函数时注意GetProcAddress(hInst,"add")中第二个参数是否为动态链接库导出的函数名,因为在生成动态库时可能会改变动态库导出函数的函数名,加上修饰符(6)dll初始化全局变量时,全局变量要放在共享数据断,并且初始化每一个变量,在StartHook函数里初始化其值,记得一进函数就初始化(7)调试时,编译器会自动查找其目录下(不含debug和release目录)的dll文件,所以dll文件应该放在主文件目录下,但生成的应用程序则只会在同一个目录下找dll(不需要lib文件),所以单纯的运行exe,不通过编译器,那就要把dll文件放在与exe相同的目录下(8)用#pragma comment(lib,"dllTest.lib")导入lib文件,不需要在设置里修改(9) dll里的指针变量不要用newDLL 调用方式DLL(动态连接库),可以分为动态调用于静态调用。

dlsym用法

dlsym用法

dlsym用法一、概述dlsym是Linux系统中的一个动态链接库函数,用于在运行时查找符号(函数、变量等)在动态链接库中的地址,从而实现动态链接库的加载和使用。

在C语言程序中,经常需要使用动态链接库来扩展程序的功能,这时就需要使用dlsym来加载和调用动态链接库中的符号。

二、dlsym函数的使用dlsym函数的原型如下:```cvoid*dlsym(void*handle,constchar*symbol);```其中,handle是指向动态链接库加载完成的句柄,symbol是要查找的符号名称。

如果符号存在并且可加载,dlsym函数会返回该符号在动态链接库中的地址,否则返回NULL。

使用dlsym函数的一般步骤如下:1.加载动态链接库,可以使用dlopen函数。

2.获取动态链接库的句柄,可以使用dlsym函数或者通过系统调用来获取。

3.使用获取到的句柄和符号名称调用dlsym函数来查找符号地址。

4.使用查找到的符号地址进行调用,例如调用函数或者访问变量等。

下面是一个简单的示例代码:```c#include<stdio.h>#include<dlfcn.h>intmain(){void*handle;int(*add)(int,int);//定义一个函数指针,指向add函数//加载动态链接库handle=dlopen("/path/to/libexample.so",RTLD_LAZY);if(!handle){fprintf(stderr,"Failedtoloadlibrary:%s\n",dlerror()); return1;}//获取add函数的地址并赋值给函数指针*(void**)(&add)=dlsym(handle,"add");if(!*add){fprintf(stderr,"Symbolnotfoundinlibrary\n");dlclose(handle);return1;}//调用add函数并输出结果intresult=add(2,3);printf("Result:%d\n",result);//关闭动态链接库句柄dlclose(handle);return0;}```三、注意事项在使用dlsym函数时,需要注意以下几点:1.动态链接库的路径需要正确指定,否则无法加载动态链接库。

试谈commonlisp中符号(symbol)与变量的关系,以及关于词法变量与动态变量的例子

试谈commonlisp中符号(symbol)与变量的关系,以及关于词法变量与动态变量的例子

试谈commonlisp中符号(symbol)与变量的关系,以及关于词法变量与动态变量的例⼦本⽂⼀些论点基于个⼈的推断与总结,请保持独⽴思考的能⼒,本⽂中所做的实验你也可以动⼿做⼀下符号(symbol)与变量变量是符号,但符号不⼀定是变量。

CL-USER> (symbol-value 'app)error: The variable APP is unbound.CL-USER> (setq app 3333)3333CL-USER> (symbolp app) ;注意这⾥最终求值的应该是(symbolp 3333)NILCL-USER> (symbolp 'app)TCL-USER> (symbol-value 'app)3333CL-USER> (symbol-function 'app)error: The function COMMON-LISP-USER::APP is undefinedCL-USER> (defun app (x) (* 2 x))APPCL-USER> (symbol-function 'app)#<FUNCTION APP>CL-USER> (+ 1 app)3334CL-USER> (app 1234)2468由此,我认为,符号和值绑定后,符号有被看作变量的资格;符号和函数绑定后,符号有被看作函数的资格。

根据符号所处的上下⽂,符号可以被看作变量或函数。

另外⼀个可能看起来很奇怪的例⼦:CL-USER> (setq appp (function (lambda (x) (* x 4))))#<FUNCTION (LAMBDA (X)) {23E7131D}>CL-USER> (symbol-value 'appp)#<FUNCTION (LAMBDA (X)) {23E7131D}>CL-USER> (symbol-function 'appp)error: The function COMMON-LISP-USER::APPP is undefinedCL-USER> (mapcar #'appp '(1 2 3))error: The function COMMON-LISP-USER::APPP is undefinedCL-USER> (mapcar appp '(1 2 3)) ;;这说明函数在符号appp的value槽中(4 8 12)关于词法变量,动态变量的例⼦test 1CL-USER> (defun show-my () (print a));(省略输出和警告信息)(函数应该是定义成功了)CL-USER> (let ((a 3)) (show-my))==>error: The variable A is unbound.test 2CL-USER> (defparameter *a* 1)CL-USER> (defun show-my () (print *a*))CL-USER> (let ((*a* 3)) (show-my));这⾥有个换⾏符,这是print的作⽤。

dlsym 用法

dlsym 用法

dlsym 用法摘要:1.dlsym 函数介绍2.dlsym 函数的参数3.dlsym 函数的返回值4.dlsym 函数在编程中的应用5.dlsym 函数的注意事项正文:dlsym 函数是C 语言库函数之一,用于动态链接库(DLL)中符号(变量或函数)的查找。

它可以在运行时动态地加载库并查找指定的符号,为程序提供灵活性。

以下是dlsym 函数的基本用法和注意事项。

1.dlsym 函数介绍dlsym 函数的原型为:```void *dlsym(void *handle, const char *symbol);```其中,`handle` 参数是库句柄,`symbol` 参数是要查找的符号名称。

函数返回一个指向所查找符号的指针,如果查找失败则返回NULL。

2.dlsym 函数的参数- `handle`:库句柄,表示要查找的库。

通常通过调用dlopen 函数打开库文件并返回其句柄。

- `symbol`:要查找的符号名称,可以是变量名或函数名。

请注意,符号名称需要与库中的符号名称完全匹配,包括大小写。

3.dlsym 函数的返回值dlsym 函数返回一个指向所查找符号的指针。

如果查找成功,返回值是一个有效的指针;如果查找失败,返回NULL。

在使用返回值之前,请务必检查其是否为NULL,以避免潜在的错误。

4.dlsym 函数在编程中的应用dlsym 函数在编程中常用于动态加载库、查找库中的函数或变量。

例如,可以在运行时根据用户的选择加载不同的库,然后调用库中的函数。

此外,还可以在调试和诊断过程中使用dlsym 函数来查找特定符号的地址。

5.dlsym 函数的注意事项- 在使用dlsym 函数之前,请确保库已经通过dlopen 函数打开。

- 符号名称需要与库中的符号名称完全匹配,包括大小写。

如果名称中有通配符(如`*` 或`?`),请确保以正确的模式匹配。

- 如果查找的符号在库中不存在,dlsym 函数将返回NULL。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

动态连接库和符号(symbol)shared library (.so)"Program Library Howto-Shared Libraries"是很好的材料, 下面的内容多是据此整理的.定义:Shared libraries are libraries that are loaded by programs when they start.使用shared library(共享库)会有很多好处, 比如软件升级, 不难想象.命名约定:1. soname: 每个共享库都有一个soname, 形式为"libNAME.so.x", 其中x是版本号. 如"libc.so.6".2. real name: 真正的库文件, 一般形式为"soname.y[.z]", 即"libName.so.x.y[.z]", 其中y是minor number, z是release number, 是可选的. 如"libattr.so.1.1.0".3. linker name: compiler用来请求库时使用的名字, 一般是没有版本号的soname.放置位置&amp; load/preload:共享库一般放在一些约定的目录下, 如/usr/lib/, /usr/local/lib, /lib/等. 这其实是遵循FHS的, 比如/usr/local/lib下放置的一般是用户开发的库.在启动程序时, program loader(ld-linux.so.x)会找到并加载程序需要的共享库, loader查找的路径一般就是上述的几个目录, 这些目录在/etc/ld.so.conf文件中配置.如果只想覆盖共享库的某几个函数, 保持其余函数不变, 则可以将共享库名字和函数名字输入到/etc/ld.so.preload中, 这里面定义的规则会覆盖标准规则.cache arrangement &amp; ldconfig实际上, 在启动程序时再去搜寻所需的共享库不是高效做法, 所以loader使用了cache. ldconfig的作用就是读取文件/etc/ld.so.conf, 在各个库目录中, 对共享库设置合适的symbolic link(使得遵守命名约定), 然后写入某种数据到/etc/ld.so.cache, 这个文件再今后就被其他程序使用, 从而大幅提升了共享库的查找速度.所以在每加入/移除一个共享库, 或者修改了/etc/ld.so.conf(即修改库目录)的时候, 最要运行ldconfig.创建共享库step1. 编译出object files, 需要使用-fPIC或-fpic flag. fPIC和fpic的区别是, 前者生成的文件更大, 不过具有更好的平台无关性, 后者恰好相反. 这说明前者为了platform-independence做了更多工作.step2. 用-Wl向linker传递参数. 如: "gcc -shared-Wl,-soname,libmystuff.so.1 -o libmystuff.so.1.0.1 a.o b.o -lc".step3. 把共享库拷贝到约定的某个目录下即可, 如/usr/local/lib.step4. ldconfig -n /path/to/lib.elfelf的内容参考"elf &amp; libelf, elftoolchain", 它是一种格式,也是一种规范, 可以用libelf写程序去操作它, 可以用objdump、nm和readelf去读取elf文件的内容.symbols我也已经熟悉共享库了, 我知道ldconfig的作用, 我知道常用的库放置目录, 我知道ltrace, ldd可以用来帮助确认某程序和某些共享库的关联关系是否正确.所以, 如果没有symbols这一节, 本篇文章存在的意义不大. "Inside ELF Symbol Tables"是绝佳的资料, 当然正如很多网文一样, 它仅是帮助理解, 而不涉及很深的细节. 细节标准什么的还是要看书和文档了, 这方面很不错的书籍就是校友的&lt;程序员的自我修养&gt;了.查看elf规范, 你必然可以看到symtab和dynsym, 如"ELF-64 Object File Format"中"4.Sections"就列出了标准的sections, .symtab和.dynsym就是其中之二.实际上, 我们知道机器可执行的是machine code, 而我们使用的高级语言编程, 并不是利用晦涩的机器码, 而是用human-readable的变量名, 函数名等, 这些名字就是symbolic name. 编译器在编译时收集symbol信息, 并储存在object file的.symtab和.dynsym中. symbols是linker和debugger所必需的信息, 如果没有symbols, 试想debugger如何能展示给用户调试信息了? 如果没有symbol, 而只有地址(相对于object file的offset), linker如何能够链接多个object file了?对于linker和symbol, 我们可以做个小实验: // 编写一个简单的a.c$ cat a.cvoid func(void){printf("call func()\n");}$ nm a.o00000000 T funcU puts// 编写一个简单的main.c$ cat main.c#include &lt;stdio.h&gt;extern void func(void);int main({func();return 0;}$ nm main.oU func00000000 T main// 正常情况下$ gcc main.o a.o -o main$ ./maincall func()// 为了验证symbol对于linker来说是必需品, 我做如下操作$ file a.oa.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped$ strip a.o$ file a.oa.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), stripped$ gcc main.o a.o -o mainmain.o: In function `main':/home/xan/lab/main.c:7: undefined reference to `func'collect2: ld returned 1 exit status这个小实验证实了symbols对于linker的重要性, 同时使用file看出"not stripped"-&gt;"stripped"的变化, 说的就是去除了symbols信息.现在假使我们生成了最后的可执行文件(当然是elf格式了), 那么这个elf中是否包含symbols呢? 其中又是否需要symbols呢?不妨先下结论: 一般地, 生成的可执行文件都是包含symbols, 不过这些信息不是程序执行所必需的, 可以通过strip(Discard symbols from object files)去除.同样可以做个小实验:// 仍用上面实验的代码$ file mainmain: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped$ ./maincall func()$ strip main$ file mainmain: ELF 32-bit LSB executable, Intel 80386, version 1(SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped$ ./maincall func()$这个小实验证实了symbols对于可执行文件来说不是必需的, 这是因为可执行的代码都是machine code, 只需要address信息, 无需symbol信息.对于elf和symbols, 还是好理解的啦. 就是我elf文件中留了一席之地给你放symbols, compiler在生成elf时会往其中填充. debugger/nm/readelf等可以来读取. 不过这些symbols不是程序执行必需的, 所以完全可以去除, 只不过去除之后, debugger就读不到信息了.而对于共享库来说, 情况略复杂些了. 我们来特别说明.共享库和symbols在继续下去之前, 先来看两个事实.$ ldd /bin/lslinux-gate.so.1 =&gt; (0xb7711000)libselinux.so.1 =&gt; /lib/libselinux.so.1(0xb76e5000)librt.so.1 =&gt; /lib/i686/cmov/librt.so.1(0xb76dc000)libacl.so.1 =&gt; /lib/libacl.so.1 (0xb76d4000)libc.so.6 =&gt; /lib/i686/cmov/libc.so.6 (0xb758d000)libdl.so.2 =&gt; /lib/i686/cmov/libdl.so.2(0xb7589000)/lib/ld-linux.so.2 (0xb7712000)libpthread.so.0 =&gt; /lib/i686/cmov/libpthread.so.0 (0xb7570000)libattr.so.1 =&gt; /lib/libattr.so.1 (0xb756b000)$ nm /lib/i686/cmov/libc.so.6nm: /lib/i686/cmov/libc.so.6: no symbols --&gt; libattr, libacl也一样, 都显示"no symbols"// 而libpthread有一大串$ nm /lib/i686/cmov/libpthread.so.0 | tailU twalk@@GLIBC_2.0U uname@@GLIBC_2.0U unlink@@GLIBC_2.00000c930 t unwind_cleanup0000c970 t unwind_stop0000cfd0 W vfork0000de90 W wait0000df50 W waitpid0000c140 t walker0000d020 W write这仅仅是因为有些库做了strip, 而其他库没做strip而已? 还是说对于某些共享库来说, symbols也是必需的?目前不知答案, 分析下去.前面提到.symtab和.dynsym两个不同的symbol table, 它们有什么区别?.dynsym是.symtab的一个子集, 大家都有疑问, 为什么要两个信息重合的结构?需要先了解allocable/non-allocable ELF section, ELF文件包含一些sections(如code和data)是在运行时需要的, 这些sections被称为allocable; 而其他一些sections仅仅是linker,debugger等工具需要, 在运行时并不需要, 这些sections被称为non-allocable的. 当linker构建ELF文件时, 它把allocable的数据放到一个地方, 将non-allocable的数据放到其他地方. 当OS加载ELF文件时, 仅仅allocable的数据被映射到内存, non-allocable的数据仍静静地呆在文件里不被处理. strip就是用来移除某些non-allocable sections的..symtab包含大量linker,debugger需要的数据, 但并不为runtime必需, 它是non-allocable的; .dynsym包含.symtab的一个子集, 比如共享库所需要在runtime加载的函数对应的symbols, 它世allocable的.因此, 得到答案:1. strip移除的应是.symtab.2. nm读取的应是.symtab: 上面发现的libattr等nm结果为空, libpthread nm结果非空应是正常的.3. 共享库包含的.dynsym是runtime必需的, 是allocable的. 可做验证, 期望的结果为:1. strip libpthread, ls依然能够工作.2. strip libpthread, nm libpthread得到结果为空.3. 可以通过设置nm options, 或使用readelf读出.dynsym的内容.$ sudo strip /lib/i686/cmov/libpthread-2.11.3.so$ file /lib/i686/cmov/libpthread-2.11.3.so/lib/i686/cmov/libpthread-2.11.3.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped$ ls...(输出正确结果)$ nm /lib/i686/cmov/libpthread-2.11.3.sonm: /lib/i686/cmov/libpthread-2.11.3.so: no symbols$ readelf -s /lib/i686/cmov/libpthread-2.11.3.so | tail322: 0000b6a0 292 FUNC GLOBAL DEFAULT 13 __pthread_clock_gettime@@GLIBC_PRIV ATE323: 0000ec30 46 FUNC GLOBAL DEFAULT 13 pthread_mutex_consistent_@@GLIBC_2.4324: 0000b3a0 50 FUNC GLOBAL DEFAULT 13 pthread_testcancel@@GLIBC_2.0325: 0000d6b0 111 FUNC WEAK DEFAULT 13 fsync@@GLIBC_2.0326: 0000d1f0 180 FUNC WEAK DEFAULT 13 fcntl@@GLIBC_2.0327: 0000dde0 176 FUNC WEAK DEFAULT 13tcdrain@@GLIBC_2.0328: 00009390 7 FUNC GLOBAL DEFAULT 13 pthread_mutexattr_destroy@@GLIBC_2.0329: 00006de0 23 FUNC GLOBAL DEFAULT 13 pthread_yield@@GLIBC_2.2330: 000077c0 259 FUNC GLOBAL DEFAULT 13 pthread_mutex_init@@GLIBC_2.0331: 000093c0 49 FUNC GLOBAL DEFAULT 13 pthread_mutexattr_setpsha@@GLIBC_2.2$ readelf -s /lib/libattr.so.1.1.0 | tail48: 00002f50 50 FUNC GLOBAL DEFAULT 13 lremovexattr@@ATTR_1.049: 00003010 57 FUNC GLOBAL DEFAULT 13 llistxattr@@ATTR_1.050: 00002ae0 50 FUNC GLOBAL DEFAULT 13 attr_copy_check_permissio@@ATTR_1.151: 00001b50 259 FUNC GLOBAL DEFAULT 13 attr_set@@ATTR_1.052: 00002b20 1002 FUNC GLOBAL DEFAULT 13 attr_copy_action53: 000031f0 71 FUNC GLOBAL DEFAULT 13setxattr@@ATTR_1.054: 00001380 543 FUNC GLOBAL DEFAULT 13 attr_list@@ATTR_1.255: 000030d0 64 FUNC GLOBAL DEFAULT 13 lgetxattr@@ATTR_1.056: 00002fd0 57 FUNC GLOBAL DEFAULT 13 flistxattr@@ATTR_1.057: 00002f10 50 FUNC GLOBAL DEFAULT 13 fremovexattr@@ATTR_1.0至此, 对symbols和共享库,ELF的关系的了解告一段落. more既然已经说到共享库(shared library), 不妨稍微提一下动态装载库(Dynamically Loaded Libraries), 共享库是在程序startup 时被加载, 而DLL(注意区别于windows下的概念)则是在程序运行过程中显式被加载, 实际上就是调用dlopen,dlsym等接口显式地打开共享库, 显示地查找库中的symbol, 然后找到对应的代码去执行.How To Write Shared Libraries by Ulrich Drepper.--EOF--。

相关文档
最新文档