知识大全 Delphi for Linux中应用共享对象库

Posted 函数

篇首语:树怕烂根,人怕无志。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Delphi for Linux中应用共享对象库相关的知识,希望对你有一定的参考价值。

Delphi for Linux中应用共享对象库  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  本文用通俗易懂的语言介绍Linux平台上共享对象库(SO)的基本概念及主要优点 通过剖析在Delphi for Linux中应用SO与在Delphi for Windows中应用DLL的异同 以编程实例讲述了Linux平台的SO库文件的组成 SO库文件的函数重载 特殊编译指令 采用Delphi for Linux创建SO的编程规则 使用前的Linux系统设置 以及在Delphi for Linux中用隐式或显式链接方法装入和使用SO函数的基本方法 经验及技巧 并对应用SO可能出现的问题进行了探讨和分析

  一 共享对象库基本概念

  Delphi for Linux是Borland公司推出的基于Linux平台的 面向对象的可视化开发工具 是目前Linux平台上很好的应用开发工具 Delphi for Linux也称Kylix 大家用Kylix开发Linux应用程序时 可能使用过Linux操作系统本身带的大量SO文件 SO是一种特殊的运行文件 包含若干方法 对象和资源 它不能直接运行 但可以被Kylix应用程序或其它可执行文件动态调用 SO文件扩展名为 so 编译前源文件扩展名为 dpr 本文所举例子均在Red Hat Linux 及Kylix 环境下调试编译通过 并可正常运行

  图 是Kylix主程序与SO库的层次关系图 从中可看出使用SO库有以下几个优点

图 Kylix主程序与SO库的层次关系图

  ◆ 多个Kylix程序或它的多个单元文件可通过接口共用一个SO库文件 另一方面 某一个Kylix程序 可通过多个接口使用多个SO库文件 这样 SO变成一种可共用的资源 实现真正的 资源共享 大大缩小了Kylix应用程序的执行代码 增强了软件的可重用性

  ◆ 将SO文件作为Kylix应用程序的公共调用模块设计时 由于其独立于应用程序 软件升级时只需修改SO库文件及编译SO 无需更改及重编译Kylix应用主程序

  ◆ 不仅可使用Kylix编写SO库 还可使用C或C++等常用语言来编写 只要遵循特定的接口规范

  二 共享对象库的创建

   SO库文件的构成

  SO库文件和Kylix标准单元文件的内部结构基本相同 也有声明 实现及初始化部分 区别之一在于SO库只是其它程序可以调用的方法(包括函数及过程)集合 区别之二库程序以library关键字而非project开头启动其项目文件 库程序包含有exports语句 其列出要向外部提供的导出函数及过程 下面是SO库文件代码的简单例子 用以说明其构成

library MyFirstSO usesSysUtils classes Delphi for Windows 中引用类库为Windows function Add (A Char B Char) Integer cdecl overload beginResult := Ord (A) + Ord (B) end function Add (A Integer B Integer) Integer cdecl overload beginResult := A + B end function Double (N Integer) Integer cdeclbeginResult := N * end;exportsAdd (A Integer B Integer) Add (A Char B Char) name AddChar Double

   SO库文件中的函数重载

  SO库也可以使用重载函数(即多个函数使用相同名称 不同参数) 使用时需在重载的函数声明后标上overload指令 Kylix可以用原名称导出一个重载函数 在exports从句中表示其参数表 若要导出多个重载函数 则要在exports从句中用name字句指定不同名称 以区别重载 这可从上面的例子MyFirstSO中看出 Add是重载函数 为调用时区分 一个用原函数声明Add导出 另一个用AddChar导出

   SO库的特殊编译指令

  编译后生成的SO库运行文件使用lib前缀和 so扩展名 考虑到实际命名规则与版本和支持符号链 Kylix在Object Pascal语言中引入了几个特殊编译指令 这些在Delphi中没有什么意义 库源文件MyFirstSO dpr编译后产生的执行文件为libMyFirstSO so

  ◆ $SOPREFIX 改变名称前缀 默认为lib(正常库)或bpl(Kylix包) 用前缀区别两种库是因为Linux的库用单一扩展( so)

  ◆ $SOSUFFIX 在库名与扩展名之间增加文本 指定版本或其它信息

  ◆ $SOVERSION 在扩展名之后增加版本号

  ◆ $SONAME 表示相关符号链名 由编译器自动生成

  例如 下列代码生成库libsimple so 和符号链libsimple so

library simple uses SysUtils Classes //函数定义省略$SOVERSION $SONAME libsimple so

  三 共享对象库的使用

  Kylix应用程序使用SO库时 可以采用两种方式 一种是隐式链接(Implicit linking) 也称静态装入 另一种是显式链接(Explicit Linking) 也称动态装入 下面分别介绍这两种链接方式的使用方法 技巧及将窗体对象放入SO库的技术

   使用前的系统设置

  自定义SO库建好后 Kylix应用程序调用时会报错 这是因为Kylix找不到新建库 必须对系统进行相关设置 这与在Delphi for Windows中使用DLL库不同 DLL库建好后只需将编译后的DLL文件放到Delphi主程序目录下即可使用 操作步骤如下

  ◆ 将编译好的SO库文件放到Linux系统库目录/lib或/usr/lib下 或者在Linux系统库路径shell变量LD_LIBRARY_PATH中加入自定义SO库文件所在路径

  ◆ 在根用户(root)下 用ldconfig命令刷新库缓冲区

  ◆ 对Kylix执行文件使用ldd命令 查看该程序所关联的SO库

   隐式链接

  隐式链接是指在应用程序开始执行时就将SO库文件加载到应用程序中 实现隐式链接并不难 只需在应用程序中加入库函数的声明语句及库的external定义从句 则库函数可以和一般局部函数一样使用 比如 要使用libMyFirstSO so中的Add函数 则只要在应用程序中增加下面语句

function Add (A Integer B Integer) Integer cdecl

external libMyFirstSO so

     显式链接

  显式链接是应用程序在执行过程中可根据实际需要随时加载SO库文件 也可以随时卸载SO库文件 还可在运行时进行SO库的切换 而这些是隐式链接无法做到的 与隐式链接相比 显式链接具有更大的灵活性

  在Kylix中 要动态装入库和调用导出函数可以用Delphi仿真代码或自然Linux方法 下面分别介绍这两种方法

  ( )用Delphi仿真代码动态装入

  在Windows中动态装入DLL是用Windows API函数—LoadLibrary或Delphi提供的SafeLoadLibrary函数完成的 找到库后 程序调用Windows API函数—GetProcAddress搜索DLL导出函数 若找到匹配 则返回所请求函数指针 并将这个函数指针转换成适当类型和调用 使用完后调用FreeLibrary 从内存中释放库

  Kylix中使用Pascal RTL仿真函数实现SO库动态装入 下面的例子只列出Kylix应用程序中与动态链接相关部分 而非完整Kylix单元文件代码

unit DynaForm;interfaceusesSysUtils Classes Qcontrols Qforms typeTForm = class(TForm)Button : TButton;procedure Button Click(Sender: TObject);end;var Form TForm implementation$R * XFMtype TComputeInteger = function (x Integer y Integer) Integer cdecl //调用库函数接口类型定义procedure TForm Button Click(Sender TObject) var Handle Thandle Compute TputeInteger beginHandle:=LoadLibrary( libMyFirstSO so ) //动态装入库if Handle<> then //找到库beginCompute:=TputeInteger(GetProcAddress(Handle Add ) //搜索库函数Add 并返回函数指针if Assigned(Compute) thenShowMessage(IntToStr(Compute( )) //使用库函数FreeLibrary(Handle) //释放库endelseShowMessage( Library not found ) end

  ( )用Linux自然代码动态装入

  也可以使用Libc系统单元中的低级Linux函数 这样可使用更多参数 更好地控制系统 使用的Linux函数分别为dlopen(打开并装入库函数) dlsym(搜索库函数) dlclose(释放库) 因此 上例中调用库的代码变为

procedure TForm Button Click(Sender TObject) var Handle Pointer Compute TputeInteger beginHandle:=dlopen( libMyFirstSO so ) //动态装入库if Handle<>nil then //找到库beginCompute:=TputeInteger(dlsym(Handle Add ) //搜索库函数Add 并返回函数指针if Assigned(Compute) thenShowMessage(IntToStr(Compute( )) //使用库函数dlclose(Handle) //释放库endelseShowMessage( Library not found ) end

  ( )SO库中窗体对象的使用

  除了包含函数和过程的库之外 还可以将Kylix建立的窗体放在共享对象中 这可以是对话框或其它窗体

  生成新的库对象之后 只要在库源文件的声明部分增加对窗体单元文件的引用 然后在窗体单元文件中编写生成和使用窗体的导出函数 下面的例子实现Kylix主程序通过调用SO库窗体处理函数 来激活模态对话框以选择颜色 并更新应用主窗体颜色 步骤如下

  ◆ 创建具有特定功能的窗体单元文件ScrollF 窗体对象为FormScroll 下面代码仅用于说明 并非完整的程序

unit ScrollF;interfaceusesSysUtils Classes QControls QForms;typeTFormScroll = class(TForm) //对象及方法定义省略end;var FormScroll TformScroll

  ◆ 在窗体单元文件ScrollF的实现部分编写使用窗体FormScroll的导出函数GetColor 其功能是激活对话框对象FormScroll以选择颜色 并将颜色值返回 代码如下

function GetColor (Col: LongInt) LongInt cdecl varFormScroll TformScroll beginResult := Col; //函数返回缺省值tryFormScroll := TFormScroll Create (Application);tryFormScroll SelectedColor := Col; //初始化颜色if FormScroll ShowModal = mrOK then //显示对话框Result := FormScroll SelectedColor; //返回颜色值finallyFormScroll Free;end;excepton E: Exception doMessageDlg ( Error in FormDLL: +E Message mtError [mbOK] );end;end;

  ◆ 在窗体文件ScrollF的定义部分增加导出函数GetColor的声明 代码如下

function GetColor (Col LongInt) LongInt cdecl

  ◆ 在库源文件FormSO dpr的定义部分增加对窗体单元ScrollF的引用 代码如下

library FormSO usesScrollF in ScrollF pas FormScroll exportsGetColor end

  ◆ 编译库文件FormSO dpr 生成SO库执行文件libFormSO so

  现在 就可以在Kylix应用程序中以隐式或动态方法来调用库libFormSO so中的窗体类函数GetColor

  四 应注意的问题

  尽管SO库为开发者带来诸多好处 但由于其与一般Kylix程序的差异 如果把它当作后者一样使用可能会带来一些问题 下面列出使用中可能出现的几个问题

  ( )在SO库中大量引用CLX图形类库 将对SO库带来不良影响

  ( )如果编译库和主执行文件而不运行库 则会得到CLX代码和数据的两个拷贝 例如 可能得到两个不同的全局Application对象 库中的Application对象不能正确初始化

  ( )如果库中需要大量调用CLX图形类或CLX控件类对象 建议最好使用软件包(Package)—一种特殊的共享库 而若库以非图形类处理为主 如数值计算 则用SO库更为方便

cha138/Article/program/Delphi/201311/25048

相关参考

知识大全 对象库的使用

  >在FORM_BUILD的对象库中点击  出现下图显示我们保存为TESTOLB  >  >双击TEST前面的图标或者点击右键的对象库都可以调出如下界面  >  >然后我们将FOR

知识大全 Delphi面向对象的编程方法(七)

Delphi面向对象的编程方法(七)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  程序库单元的

知识大全 LINUX系统中动态链接库的创建与使用

LINUX系统中动态链接库的创建与使用  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  大家都知道

知识大全 Delphi 中动态链接库(dll)的建立和使用[2]

Delphi中动态链接库(dll)的建立和使用[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

知识大全 Delphi 中动态链接库(dll)的建立和使用[1]

Delphi中动态链接库(dll)的建立和使用[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

知识大全 Delphi中动态链接库两种调用方式的比较

Delphi中动态链接库两种调用方式的比较  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!一动态链接

知识大全 Delphi8 for Microsoft® .NET与Delphi 7的区别

Delphi8forMicrosoft®.NET与Delphi7的区别  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶

知识大全 XMMS MP3 Plugin for Red Hat Linux 8.0

XMMSMP3PluginforRedHatLinux8.0  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看

知识大全 Windows与Linux间的资源共享

Windows与Linux间的资源共享  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  从Wind

知识大全 linux生成(加载)动态库静态库和加载示例方法

  动态库的生成  /*mysumc*/    复制代码代码如下:  #include<stdioh>#includesrch  intsum(intaintb)return(a+b);&