我一直在尝试为Windows 10上的Oracle Database 18c配置“外部过程”功能。
文档声称,要设置此功能,基本上只需要在extrproc.ora
中设置环境值-就我而言,它只是以下一行的内容:SET EXTPROC_DLLS=ANY
(出于测试目的)
我已经创建了一个DLL,以使用带有以下代码的Delphi来测试我的配置:
library testdll;
function Sum(x, y: Integer): Integer; stdcall;
begin
Result := x + y;
end;
function Subtract(x, y: Integer): Integer; stdcall;
begin
Result := x - y;
end;
procedure TEST; stdcall;
begin
end;
exports
TEST,
Sum,
Subtract;
begin
end.
所以我的第一个问题是:是否需要将DLL编译为x64或x86?另外,调用约定stdcall
是否与Oracle 18c兼容?
此外,我还使用以下方法在数据库中创建了“图书馆别名”:
CREATE OR REPLACE LIBRARY MySchema.TESTDLL AS 'C:\testdll.dll'
外部程序已由
发布create or replace PROCEDURE TESTPROCEDURE
AS LANGUAGE C
NAME "TEST"
LIBRARY TESTDLL;
现在我已经在数据库上进行了所有设置,我尝试调用该过程:
begin
TESTPROCEDURE();
end;
但是当我尝试调用它时,出现以下错误:
ORA-06520: PL/SQL: Fehler beim Laden der externen Library
ORA-06522: Unable to load DLL
ORA-06512: in "MySchema.TESTPROCEDURE", Zeile 1
ORA-06512: in Zeile 2
06520. 00000 - "PL/SQL: Error loading external library"
*Cause: An error was detected by PL/SQL trying to load the external
library dynamically.
*Action: Check the stacked error (if any) for more details.
信息:
extproc.exe
我如何才能正常工作并且Delphi DLL是否兼容?
这是我的listener.ora
文件:
# listener.ora Network Configuration File: C:\app\oracle\product\18.0.0\dbhomeXE\NETWORK\ADMIN\listener.ora
# Generated by Oracle configuration tools.
DEFAULT_SERVICE_LISTENER = XE
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = CLRExtProc)
(ORACLE_HOME = C:\app\oracle\product\18.0.0\dbhomeXE)
(PROGRAM = extproc)
(ENVS = "EXTPROC_DLLS=ONLY:C:\app\oracle\product\18.0.0\dbhomeXE\bin\oraclr18.dll")
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
这是我的tnsnames.ora文件:
# tnsnames.ora Network Configuration File: C:\app\oracle\product\18.0.0\dbhomeXE\NETWORK\ADMIN\tnsnames.ora
# Generated by Oracle configuration tools.
XE =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = XE)
)
)
LISTENER_XE =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
ORACLR_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
(CONNECT_DATA =
(SID = CLRExtProc)
(PRESENTATION = RO)
)
)
任何想法我的配置有什么问题吗?
编辑: 这是来自数据库的.c dll示例代码:
/*
** Copyright (c) 1997 by Oracle Corporation
**
** NAME
** EXTERN.C
**
** DESCRIPTION
** Sample Windows NT External Procedure: find_max
**
*/
#include <windows.h>
#define NullValue -1
/*
This function simply returns the returns the larger of x and y.
*/
long __declspec(dllexport) find_max(long x,
short x_indicator,
long y,
short y_indicator,
short *ret_indicator)
{
/* It can be tricky to debug DLL's that are being called by a process
that is spawned only when needed, as in this case.
Therefore try using the DebugBreak(); command.
This will start your debugger. Uncomment the following line and
you can step right into your code.
*/
/* DebugBreak(); */
/* first check to see if you have any nulls */
/* Just return a null if either x or y is null */
if ( x_indicator==NullValue || y_indicator==NullValue) {
*ret_indicator = NullValue;
return(0);
} else {
*ret_indicator = 0; /* Signify that return value is not null */
if (x >= y) return x;
else return y;
}
}
这是make.bat文件:
REM USAGE: just type MAKE
if (%PROCESSOR_ARCHITECTURE%)==(IA64) goto win64_ia64
if (%PROCESSOR_ARCHITECTURE%)==(AMD64) goto win64_amd64
cl -I. /LD -Zi extern.c /link msvcrt.lib /nod:libcmt /DLL
goto fi
:win64_ia64
cl /DWIN64 /D_WIN64 /DSS_64BIT_SERVER /D_IA64_=1 -I. /LD -Zi extern.c /link msvcrt.lib /nod:libcmt /DLL
goto fi
:win64_amd64
cl /GS- /DWIN64 /D_WIN64 /DSS_64BIT_SERVER /D_AMD64_=1 -I. /LD -Zi extern.c /link msvcrt.lib /MACHINE:AMD64 /nod:libcmt /DLL
goto fi
:fi
答案 0 :(得分:1)
根据提供的信息,我可以看到以下内容:
cdecl
。