線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3934
推到 Plurk!
推到 Facebook!

kylix如何调用别的.so

尚未結案
anqin
一般會員


發表:3
回覆:1
積分:0
註冊:2004-09-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-11-07 21:52:22 IP:211.147.xxx.xxx 未訂閱
敝人以前用ANSI C 开发了一个函数库,并且已打成,so文件。 现在想在kylix中调用这个.so,请问一下各位大虾,怎样实现? 多谢!
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-11-08 09:23:15 IP:202.39.xxx.xxx 未訂閱
參考這篇: http://delphi.ktop.com.tw/topic.php?topic_id=21080 ■讓自己開發的 Kylix 程式能獨立執行 □方法 1. 將下列兩行加入 你自己 HOME 目錄的 .bashrc (是個隱藏檔)文字設定檔中 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/your_username/kylix3/bin export LD_LIBRARY_PATH (不過以後也只有這個 user name login 才能獨立執行 Kylix 開發的程式) □方法 2. 以 root 身分編輯 /etc/ld.so.conf 將下列一行加入 /etc/ld.so.conf 文字設定檔中 /home/your_username/kylix3/bin (或其它 Kylix程式會用到之 *.so 檔所在路徑) 編輯完存檔後記得執行 ldconfig 命令
anqin
一般會員


發表:3
回覆:1
積分:0
註冊:2004-09-21

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-11-09 14:18:23 IP:211.147.xxx.xxx 未訂閱
谢谢大侠先了... 我想大侠还没理解我的意思. 我是说,我原来有个用标准c 写的共享库(用c 编译的). 现在想在kylix中调用这个so,如何调用? 我试过用add project的方式把so加进去了,并且将这个so的include也放到路径下了.但是还是不行,连接出现错误. 请各位指教,谢谢了!
minggl
一般會員


發表:4
回覆:11
積分:8
註冊:2002-10-22

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-07-05 18:26:42 IP:210.51.xxx.xxx 訂閱
Kylix应用程序使用SO库时,可以采用两种方式:一种是隐式链接(Implicit linking),也称静态装入;另一种是显式链接(Explicit Linking),也称动态装入。下面分别介绍这两种链接方式的使用方法、技巧及将窗体对象放入SO库的技术。 

1.使用前的系统设置

自定义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库。

2.隐式链接

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

function Add (A:Integer;B:Integer):Integer;cdecl ;

external 'libMyFirstSO.so';

3.显式链接

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

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

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

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

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

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;


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

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

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;


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

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

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

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

unit ScrollF;
interface
uses
  SysUtils, Classes, QControls, QForms;
type
  TFormScroll = class(TForm)   //对象及方法定义省略
end;
var FormScroll:TformScroll;


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

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.


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

现在,就可以在Kylix应用程序中以隐式或动态方法来调用库libFormSO.so中的窗体类函数GetColor。
系統時間:2017-09-24 13:00:17
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!