为 Linux 运用程序编写 DLL-C / C++-优质IT资源分享社区

admin
管理员
管理员
  • UID1
  • 粉丝29
  • 关注4
  • 发帖数581
  • 社区居民
  • 忠实会员
  • 原创写手
阅读:209回复:0

  为 Linux 运用程序编写 DLL

楼主#
更多 发布于:2016-05-19 16:23

The Standard C Library for

Linux, Part one:file functions

By James M. Rogers

在仅仅只会编写插件的时分为何要编写全部运用程序?

Allen Wilson

(wilsona@us.ibm.com)

电子商务规划师,IBM

2001 年 10 月

插件和 DLL

一般是用来无须编写全部新运用程序而增加功用的极好办法。在 Linux 中,插件和 DLL 以动态库方法完成。电子商务参谋兼规划师 Allen Wilson

介绍了动态库而且向您演示了如何在某个运用程序正在运转以后运用动态库来改动该运用程序。

Internet 浏览器用户十分了解插件的概念。从 Web

上下载插件,一般这些插件为浏览器的音频、视频以及特殊效果供给增强支撑。一般来讲,在不更改原有运用程序的情况下,插件为现有运用程序供给新功用。

DLL

是程序函数,它们在规划和构建运用程序时为该程序所知。规划运用程序的主程序时运用程序结构或底板,这些程序结构或底板在运转时挑选性地装入所需的 dll,这些 dll

位于磁盘上同主程序别离的一些文件中。这一打包和动态装入供给了灵敏的晋级、保护、以及答应战略。

随 Linux

一起交给的还有几千条指令和运用程序,它们最少都需求 libc 库函数。假如 libc

函数与每一个运用程序都打包在一起,那么磁盘大将会呈现几千个一样函数的副本。Linux

构建这些运用程序,以运用一般所需的体系库的单个体系级副本,而不浪费磁盘空间。Linux

甚至做得十分好,每个需求公共体系库函数的进程运用单个的体系级内的副本,一次性将该副本装入到内存并为各进程所同享。

在 Linux 中,插件和 dll

以动态库方法完成。这篇文章的余下有些是在运用程序运转以后运用动态库更改该运用程序的示例。

Linux 动态连接

Linux

中的运用程序以以下两种方法之一连接到外部函数:要么在构建时与静态库(lib*.a)静态地连接,而且将库代码包括在该运用程序的可履行文件里;要么在运转时与同享库(lib*.so)动态地连接。经过动态连接装入器,将动态库映射进运用程序的可履行内存中。在发动运用程序之前,动态连接装入器将所需的同享方针库映射到运用程序的内存,或许运用体系同享的方针并为运用程序解析所需的外部引证。如今运用程序就能够运转了。

作为示例,下面有一个演示 Linux

中对动态连接库的缺省运用的小程序:

main()

{

printf("Hello world

");

}

当运用 gcc 编译 hello.c 时,就创立了一个名为

a.out 的可履行文件。经过运用 Linux 指令 ldd a.out(该指令打印出同享库的彼此依赖性),能够看出所需的同享库是:

libc.so.6 => /lib/libc.so.6

(0x4001d000)

/lib/ld-linux.so.2 =>

/lib/ld-linux.so.2 (0x40000000)

运用一样的动态连接装入器在运用程序运转以后将 dll

映射进运用程序的内存。经过运用 Linux

动态装入器例程,运用程序操控装入哪一个动态库以及调用库中的哪一个函数,以履行装入和连接以及回来所需进口点的地址。

Linux dll 函数

Linux 供给 4 个库函数(dlopen, dlerror,

dlsym 和 dlclose),一个 include 文件(dlfcn.h)以及两个同享库(静态库 libdl.a 和动态库

libdl.so),以支撑动态连接装入器。这些库函数是:

dlopen

将同享方针文件翻开而且映射到内存中,而且回来句柄

dlsym 回来一个指向被恳求进口点的指针

dlerror 回来 NULL 或许一个指向描绘近来过错的

ASCII 字符串的指针

dlclose 封闭句柄而且撤销同享方针文件的映射

动态连接装入器例程 dlopen

需求在文件体系中查找同享方针文件以翻开文件并创立句柄。有 4 种方法用以指定文件的方位:

dlopen call 中的肯定文件途径

在 LD_LIBRARY_PATH

环境变量中指定的目录中

在 /etc/ld.so.cache 中指定的库列表当中

先在 /usr/lib 当中,然后在 /lib 当中

dll 示例:小的 C 程序和 dlTest

动态连接装入器示例程序是一个小的 C 程序,该程序被规划用来操练

dl 例程。该程序根据每个人都编写过的一个 C 程序,它将“Hello World”打印到操控台上。开始打印的音讯是“HeLlO

WoRlD”。该测试程序连接到再次打印该音讯的两个函数上:首次都用大写字符,第2次都用小写字符。

以下是该程序的概要:

界说 dll include 文件 dlfcn.h

和所需的变量。 最少需求这些变量:

到同享库文件的句柄

指向被映射函数进口点的指针

指向过错字符串的指针

打印初始音讯,“HeLlO WoRlD”。

运用肯定途径“/home/dlTest/UPPERCASE.so”和选项

RTLD_LAZY,dlopen 翻开 UPPERCASE dll 的同享方针文件并回来句柄。

选项 RTLD_LAZY 推延解析 dll 的外部引证,直到

dll 被履行。

选项 RTLD_NOW 在 dlopen

回来之前解析一切的外部引证。

dlsym 回来进口点 printUPPERCASE

的地址。

调用 printUPPERCASE

而且打印修改正的音讯“HELLO WORLD”。

dlclose 封闭到 UPPERCASE.so

的句柄,而且从内存中撤销 dll 映射。

dlopen 运用根据环境变量 LD_LIBRARY_PATH

的相对途径查找同享方针途径,来翻开 lowercase dll 的同享方针文件 lowercase.so,而且回来句柄。

dlsym 回来进口点 printLowercase

的地址。

调用 printLowercase

而且打印修改正的信息“hello world”。

dlclose 封闭到 lowercase.so

的句柄,而且从内存中撤销 dll 映射。

留意,每次调用 dlopen、dlsym 或 dlclose

以后,调用 dlerror 以获取最终的过错信息,而且打印该过错信息字符串。以下是 dlTest 的测试运转:

dlTest 2-Original message

HeLlO WoRlD

dlTest 3-Open Library with

absolute path return-(null)-

dlTest 4-Find symbol

printUPPERCASE return-(null)-

HELLO WORLD

dlTest 5-printUPPERCASE

return-(null)-

dlTest 6-Close handle

return-(null)-

dlTest 7-Open Library with

relative path return-(null)-

dlTest 8-Find symbol

printLowercase return-(null)-

hello world

dlTest 9-printLowercase

return-(null)-

dlTest 10-Close handle

return-(null)-

完好的 dlTest.c、UPPERCASE.c 和

lowercase.c 源代码清单在这篇文章后边的清单里。

构建 dlTest

启用运转时动态连接需求三步:

将 dll 编译为方位无关代码

创立 dll 同享方针文件

编译主程序并同 dl 库相连接

编译 UPPERCASE.c 和 lowercase.c 的

gcc 指令包括 -fpic 选项。选项 -fpic 和 -fPIC 致使生成的代码是方位无关的,重建同享方针库需求方位无关。-fPIC

选项发生方位无关的代码,这类代码支撑大偏移。用于 UPPERCASE.o 和 lowercase.o 的第二个 gcc 指令,带有 -shared

选项,该选项发生适合于动态连接的同享方针文件 a*.so。

用于编译和履行 dltest 的 ksh 脚本如下:

#!/bin/ksh

# Build shared library

#

#set -x

clear

#

# Shared library for dlopen

absolute path test

#

if [ -f UPPERCASE.o ]; then rm

UPPERCASE.o

fi

gcc -c -fpic UPPERCASE.c

if [ -f UPPERCASE.so ]; then rm

UPPERCASE.so

fi

gcc -shared -lc -o UPPERCASE.so

UPPERCASE.o

#

# Shared library for dlopen

relative path test

#

export LD_LIBRARY_PATH=`pwd`

if [ -f lowercase.o ]; then rm

lowercase.o

fi

gcc -c -fpic lowercase.c

if [ -f lowercase.so ]; then rm

lowercase.so

fi

gcc -shared -lc -o lowercase.so

lowercase.o

#

# Rebuild test program

#

if [ -f dlTest ]; then rm

dlTest

fi

gcc -o dlTest dlTest.c -ldl

echo Current

LD_LIBRARY_PATH=$LD_LIBRARY_PATH

dlTest

结束语

创立能在运转时被动态连接到 Linux

体系上的运用程序的同享方针代码是一项十分简略的操练。运用程序经过运用对动态连接装入器的 dlopen、dlsym 和 dlclose

函数调用来获取对同享方针文件的访问。dlerror 以字符串的方法回来任何过错,这些过错信息字符串描绘 dl

函数碰到的最终一个过错。在运转时,主运用程序运用肯定途径或相对于 LD_LIBRARY_PATH 的相对途径找到同享方针库,而且恳求所需的 dll

进口点的地址。当需求时,也可对 dll 进行直接函数调用,最终,封闭到同享方针文件的句柄,而且从内存中撤销该方针文件映射,使之不可用。

运用附加选项 -fpic 或 -fPIC

编译同享方针代码,以发生方位无关的代码,运用 -shared 选项将方针代码放进同享方针库中。

Linux

中的同享方针代码库和动态连接装入器向运用程序供给了额定的功用。减少了磁盘上和内存里的可履行文件的巨细。能够在需求时,装入可选的运用程序功用,能够在无须从头构建全部运用程序的情况下批改缺点,而且运用程序能够包括第三方的插件。

清单(运用程序和 dll)

dlTest.c:

/*************************************************************/

/* Test Linux Dynamic Function

Loading */

/* */

/* void *dlopen(const char

*filename, int flag) */

/* Opens dynamic library and

return handle */

/* */

/* const char *dlerror(voi

优质IT资源分享社区为你提供此文。 [font=Tahoma  ][font=Tahoma  ]

本站有大量优质C、C++教程视频,资料等资源,包含C,C++基础教程,高级进阶教程等等,教程视频资源涵盖传智播客,极客学院,达内,北大青鸟,猎豹网校等等IT职业培训机构的培训教学视频,价值巨大。欢迎点击下方链接查看。 [font=Tahoma  ][font=Tahoma  ]

C、C++教程视频

优质IT资源分享社区(www.itziyuan.top)
一个免费,自由,开放,共享,平等,互助的优质IT资源分享网站。
专注免费分享各大IT培训机构最新培训教学视频,为你的IT学习助力!

!!!回帖受限制请看点击这里!!!
!!!资源失效请在此版块发帖说明!!!

[PS:按 CTRL+D收藏本站网址~]

——“优质IT资源分享社区”管理员专用签名~

本版相似帖子

游客