歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux服務器 >> 為Linux應用程序編寫DLL程序函數

為Linux應用程序編寫DLL程序函數

日期:2017/3/2 16:56:57   编辑:Linux服務器

在僅僅只會編寫插件的時候為什麼要編寫整個應用程序?

插件和 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”。該測試程序鏈接到再次打印該消息的兩個函數上:第一次都用大寫字符,第二次都用小寫字符。

以下是該程序的概要:

定義 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 映射。

Copyright © Linux教程網 All Rights Reserved