如 何 在Oracle Developer/2000 中 調 用Windows API 函 數

xinxinhg發表於2004-11-10
調 用Windows API 函 數

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

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

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

---- 1. 初 始 化 外 部 函 數

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

---- (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 包 的 說 明(Package Spefication) 部 分, 輸 入 這 個PL/SQL 子 程 序 的 原 型。

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

PACKAGE WinExec IS
FUNCTION WinExec(Execfile IN VARCHAR2,
command IN PLS_INTEGER)
RETURN PLS_INTEGER;
END; /*在包說明部分,是模仿外部
函式原型的PL/SQL函式原型說明*/
PACKAGE BODY WinExec IS
lh_USER ora_ffi.libHandleType; /*定義庫柄型別變數*/
fh_WinExec ora_ffi.funcHandleType; /*定義函式柄型別變數*/

FUNCTION i_WinExec(funcHandle IN ora_ffi.funcHandleType,
Execfile IN OUT VARCHAR2,
command IN PLS_INTEGER)
RETURN PLS_INTEGER;

PRAGMA INTERFACE(C,i_WinExec,11265);
/*步驟2將一個PL/SQL子程式與外部函式相關聯*/

FUNCTION WinExec(Execfile IN VARCHAR2,
command IN PLS_INTEGER)
RETURN PLS_INTEGER
IS
execfile_l VARCHAR2(512) := Execfile;
rc PLS_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');
EXCEPTION WHEN ora_ffi.FFI_ERROR THEN
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 */

END WinExec;

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

---- 例 如:WinExec.WinExec('c:windows otepad.exe', 0)

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



[浪人仇發表]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/166555/viewspace-780318/,如需轉載,請註明出處,否則將追究法律責任。

相關文章