程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> 在Oracle/2000中調用Windows API函數

在Oracle/2000中調用Windows API函數

編輯:Oracle數據庫基礎

OracleDeveloper/2000是Oracle的微機開發工具,由於它與Oracle數據庫的緊密連接,比用PowerBuilder或其它高級語言采用ODBC與Oracle的連接享有得天獨厚的優點,越來越在Windows95和WindowsNT平台上得到廣泛應用,筆者在用其進行程序設計時感到,既然是在Windows平台上開發程序,如果能在其中應用一些WindowsAPI函數,將使Developer/2000有如虎添翼的感覺,可以大大彌補它與底層操作系統的聯系能力差、控制實時硬件設備功能差的缺點,開發出集成性更好的應用程序。

所有用第三方語言編寫的子程序對Developer/2000都稱為外部函數,WindowsAPI函數也是外部函數。這些外部函數必須包含在一個動態庫中。例如Windows操作系統下的動態鏈接庫或UNIX系統下的共享庫等。Developer/2000通過為每一個外部函數產生一個PL/SQL接口,它使用PL/SQL的語法,在程序中調用這一接口程序就可以激活這一外部函數。

對一個外部函數產生一個PL/SQL接口,需要用到內建軟件包ORA-FFI,它包含一些PL/SQL的子程序用來對外部函數生成PL/SQL接口,實際操作時可以用ProcedureBuilder產生一個程序庫,在程序庫中建立一個程序包(Package),在這個包中實現對外部函數建立連接。下面介紹這一過程的具體步驟:

1.初始化外部函數

就是說明包含外部函數的動態鏈接庫的位置,並從中分離出外部函數的原型,並將外部函數中主語言的數據類型和PL/SQL數據類型做一一對應的匹配。這是在包體(PackageBody)中進行的。具體分以下幾步:

(1)用OQA_FFI.LOAD_LIBRARY得到包含外部函數的動態鏈接庫的庫柄,此時需提供動態鏈接庫的名字和位置。

(2)用ORA_FFI.REGISTER_FUNCTION得到外部函數的函數柄,這時需提供動態鏈接庫的庫柄和外部函數名。

(3)用ORA_FFI.REGISTER_PARAMETER來注冊外部函數的參數類型,對每一個參數都要提供它的外部函數柄和相應的PL/SQL數據類型。參數注冊的順序必須與它們出現在外部函數原型中的順序一致。

(4)用ORA_FFI.REGISTER_RETURN來注冊外部函數的返回值類型,這時需要提供它的外部函數柄和相應的PL/SQL數據類型。

2.將外部函數和一個PL/SQL子程序相關聯

一個和外部函數建立關聯的PL/SQL子程序,實際上指明了外部函數的內存地址,每次調用這個子程序,實際上是調用與它相對應的外部函數。具體步驟為:

(1)用ORA_FFI.FIND_FUNCTION或ORA_FFI.REGISTER_FUNCTION得到一個函數柄。

(2)在PL/SQL包體的聲明部分,定義一個PL/SQL子程序,它的第一個參數是類型為ORA_FFI.FUNCHANDLETYPE,接下來是依次對應外部函數參數的PL/SQL數據類型的參數。

 (3)在這個PL/SQL子程序中加入一個PRAGMA接口。PRAGMA聲明就是通過將控制轉到一個內存地址,來激活這個外部函數。

3.生成一個模仿外部函數的原型的PL/SQL子程序。

這個子程序就是用戶可見的外部函數的PL/SQL接口,用戶按照它的參數類型和返回值類型來使用外部函數,具體步驟為:

(1)在包體的聲明部分,定義一個PL/SQL子程序,它的參數和返回值是和外部函數對應的PL/SQL類型。這就是模仿外部函數原型的一個子程序。

(2)在這個子程序中調用與上步生成的與外部函數相關聯的PL/SQL子程序。

(3)在PL/SQL包的說明(PackageSpefication)部分,輸入這個PL/SQL子程序的原型。

下面是一個完整的為WindowsAPI函數winexec建立PL/SQL接口的例子:

  
  PACKAGEWinExecIS
  FUNCTIONWinExec(ExecfileINVARCHAR2,
  commandINPLS_INTEGER)
  RETURNPLS_INTEGER;
  END;/*在包說明部分,是模仿外部
  函數原型的PL/SQL函數原型說明*/
  PACKAGEBODYWinExecIS
  lh_USERora_ffi.libHandleType;/*定義庫柄類型變量*/
  fh_WinExecora_ffi.funcHandleType;/*定義函數柄類型變量*/
  
  FUNCTIONi_WinExec(funcHandleINora_ffi.funcHandleType,
  ExecfileINOUTVARCHAR2,
  commandINPLS_INTEGER)
  RETURNPLS_INTEGER;
  
  PRAGMAINTERFACE(C,i_WinExec,11265);
  /*步驟2將一個PL/SQL子程序與外部函數相關聯*/
  
  FUNCTIONWinExec(ExecfileINVARCHAR2,
  commandINPLS_INTEGER)
  RETURNPLS_INTEGER
  IS
  execfile_lVARCHAR2(512):=Execfile;
  rcPLS_INTEGER;
  BEGIN
  rc:=i_WinExec(fh_WinExec,
  execfile_l,
  command);
  
  RETURN(rc);
  END;
  /*步驟3中PL/SQL模仿函數的定義,
  它實際上就是調用步驟2中與外部函數建立關聯的那個函數*/
  BEGIN
  BEGIN
  lh_USER:=ora_ffi.find_library('Kernel32.dll');
  EXCEPTIONWHENora_ffi.FFI_ERRORTHEN
  lh_USER:=ora_ffi.load_library(NULL,'kernel32.dll');
  END;/*得到動態鏈接庫的庫柄*/
  
  fh_WinExec:=ora_ffi.register_function
  (lh_USER,'WinExec',ora_ffi.PASCAL_STD);
  /*得到外部函數的函數柄*/
  ora_ffi.register_parameter(fh_WinExec,
  ORA_FFI.C_CHAR_PTR);/*參數注冊,原類型為LPCSTR*/
  ora_ffi.register_parameter(fh_WinExec,
  ORA_FFI.C_INT);/*參數注冊,原類型為UINT*/
  
  ora_ffi.register_return(fh_WinExec,
  ORA_FFI.C_INT);/*返回值注冊,原類型為BOOL*/
  
  ENDWinExec;
  

可以將多個外部函數的PL/SQL接口放在一個包內。要在Developer/2000的FormDesigner中使用這些外部函數,只要把包含這一程序包的程序庫(.PLL)附加進來,使用包名.函數名就可激活這個外部函數。

例如:WinExec.WinExec('c:\Windows\notepad.exe',0)

具體WindowsAPI函數數據類型和PL/SQL數據類型的轉換可參照Developer/2000中ProcedureBuilder幫助文件中對ORA_FFI軟件包的詳細介紹。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved