本文用通俗易懂的语言介绍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 7.3及Kylix 3.0环境下调试编译通过,并可正常运行。
library MyFirstSO;
uses
SysUtils, classes ; { Delphi for Windows 中引用类库为Windows }
function Add (A:Char;B:Char):Integer;cdecl;overload;
begin
Result := Ord (A) + Ord (B) ;
end;
function Add (A:Integer;B:Integer):Integer;cdecl;overload;
begin
Result := A + B ;
end;
function Double (N:Integer):Integer;cdecl
begin
Result := N * 2;
end;
exports
Add (A:Integer;B:Integer),
Add (A:Char;B:Char) name ''''AddChar'''',
Double;
unit DynaForm;
interface
uses
SysUtils,Classes,Qcontrols,Qforms;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var Form1:TForm1;
implementation
{$R *.XFM}
type TComputeInteger = function (x:Integer;y:Integer):Integer;cdecl;
//调用库函数接口类型定义
procedure TForm1.Button1Click(Sender:TObject);
var Handle :Thandle ;
Compute :TcomputeInteger;
begin
Handle:=LoadLibrary(''''libMyFirstSO.so'''');//动态装入库
if Handle<>0 then //找到库
begin
Compute:=TcomputeInteger(GetProcAddress(Handle,''''Add'''');
//搜索库函数Add,并返回函数指针
if Assigned(Compute) then
ShowMessage(IntToStr(Compute(10,20));//使用库函数
FreeLibrary(Handle);//释放库
end
else
ShowMessage(''''Library not found'''');
end;
procedure TForm1.Button1Click(Sender:TObject);
var Handle :Pointer ;
Compute :TcomputeInteger;
begin
Handle:=dlopen(''''libMyFirstSO.so'''');//动态装入库
if Handle<>nil then //找到库
begin
Compute:=TcomputeInteger(dlsym(Handle,''''Add'''');
//搜索库函数Add,并返回函数指针
if Assigned(Compute) then
ShowMessage(IntToStr(Compute(10,20));//使用库函数
dlclose(Handle);//释放库
end
else
ShowMessage(''''Library not found'''');
end;
function GetColor (Col: LongInt):LongInt;cdecl;
var
FormScroll:TformScroll;
begin
Result := Col; //函数返回缺省值
try
FormScroll := TFormScroll.Create (Application);
try
FormScroll.SelectedColor := Col; //初始化颜色
if FormScroll.ShowModal = mrOK then //显示对话框
Result := FormScroll.SelectedColor; //返回颜色值
finally
FormScroll.Free;
end;
except
on E: Exception do
MessageDlg (''''Error in FormDLL: '''' +E.Message, mtError, [mbOK], 0);
end;
end;
◆ 在窗体文件ScrollF的定义部分增加导出函数GetColor的声明。代码如下:
function GetColor (Col:LongInt):LongInt;cdecl;
◆ 在库源文件FormSO.dpr的定义部分增加对窗体单元ScrollF的引用。代码如下:
library FormSO;
uses
ScrollF in ''''ScrollF.pas'''' {FormScroll};
exports
GetColor;
end.