首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 調用外部 C++ 程序實戰:Library 創建、ORA-28575/ORA-06521 解決方案

     編輯:Oracle 資料庫相關知識

一、完整調用鏈路

  1. 編譯 C++ 生成 DLL(Windows)或 Shared Library(Linux);
  2. Oracle 創建 LIBRARY 對象指向文件路徑;
  3. 創建 PL/SQL 包裝函數/過程,映射外部符號;
  4. 配置 listener.ora + tnsnames.ora 支援 extproc;
  5. 調用 PL/SQL 包裝器,經 extproc 加載庫執行外部代碼。

二、代碼範例

1. C++ 源碼(關鍵:extern "C" 防止名字修飾)

#ifdef __cplusplus
extern "C" {
#endif

__declspec(dllexport) int square_of(int x) {
  return x * x;
}

#ifdef __cplusplus
}
#endif

2. 創建 Library

CREATE OR REPLACE LIBRARY mylib AS 'D:\installed\oracle\ora92\bin\test1.dll';

3. 包裝函數

CREATE OR REPLACE FUNCTION mytest1 RETURN DOUBLE PRECISION AS
  LANGUAGE C
  NAME "fnTest1"
  LIBRARY mylib
  PARAMETERS (RETURN DOUBLE);

三、高頻錯誤與解決方案

1. ORA-28575: unable to open RPC connection to external procedure agent

原因:extproc 監聽配置缺失或錯誤。

解決:

-- tnsnames.ora
EXTPROC_CONNECTION_DATA =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
    )
    (CONNECT_DATA = (SID = PLSExtProc)(PRESENTATION = RO))
  )

-- listener.ora
SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = D:\oracle\product\10.2.0\db_1)
      (PROGRAM = extproc)
    )
    (SID_DESC =
      (SID_NAME = ora10g)
      (ORACLE_HOME = D:\oracle\product\10.2.0\db_1)
    )
  )

重啟監聽器:lsnrctl reload。

2. ORA-06521: PL/SQL: Error mapping function

原因:C++ 編譯器對函數名進行 Name Mangling,導致符號不匹配。

解決:在 C++ 源碼中使用 extern "C" 包裹導出函數(見上方範例),確保導出符號為純函數名 square_of。

四、參數傳遞模式

參數類型PARAMETERS 子句C 原型
IN NUMBERPARAMETERS (x INT)int fn(int x)
OUT NUMBERPARAMETERS (y INT, RETURN INT)void fn(int *y)
IN OUT NUMBERPARAMETERS (z INT, RETURN INT)void fn(int *z)
STRINGPARAMETERS (str STRING, len INDICATOR)void fn(char *str, short *len)

五、最佳實踐清單

  1. C++ 必須 extern "C" 導出;
  2. Library 路徑使用絕對路徑,避免環境變量依賴;
  3. extproc 進程權限需能讀取 DLL 及其依賴庫;
  4. 大量調用場景考慮 連接池化 extproc 或改用 Java Stored Procedure / External Table;
  5. 詳細錯誤排查:啟用 HS_FDS_TRACE_LEVEL = DEBUG、查看 $ORACLE_HOME/hs/log 日志。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved