科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道为Linux应用程序编写DLL程序函数 (2)

为Linux应用程序编写DLL程序函数 (2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

插件和 DLL 通常是用来无须编写整个新应用程序而添加功能的极好方法。在 Linux 中,插件和 DLL 以动态库形式实现。电子商务顾问兼设计师 Allen Wilson 介绍了动态库并且向您演示了如何在某个应用程序正在运行之后使用动态库来改变该应用程序。

作者:IBM 来源:IBM 2007年10月16日

关键字: 函数 Dll Linux

  • 评论
  • 分享微博
  • 分享邮件
 

选项 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 进行间接函数调用,最后,关闭到共享目标文件的句柄,并且从内存中取消该目标文件映射,使之不可用。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章