External Routines
I try make the external routine writen in C. Function writen in C and stored in D:\extproc\zzz1.dll
I make the library and function
CREATE or replace LIBRARY externProcedures AS 'D:\extproc\zzz1.dll'
create or replace function pls_max(x binary_integer)
return binary_integer as
external library externProcedures
name "find_max" language C parameters (x long);
Then i execute SQl: select pls_max(10) from dual;
And got the error
ERROR at line 1:
ORA-06521: PL/SQL: Error mapping function
ORA-06522: Unable to load symbol from DLL
Where is error?
Has anyone worked out how to answer this?
Kind Regards
Richard
Similar Messages
-
Hi,
I have created an external routine as follows
CREATE OR REPLACE PROCEDURE shel(command IN char)
AS EXTERNAL
NAME "sh"
LIBRARY shell_lib
LANGUAGE C
PARAMETERS (command string);
whne i ma trying to runthe above external routine i am getting the following error.
ORA-28575: unable to open RPC connection to external procedure agent
I configured the listener.ora (server) and tnsnames.ora (client) as follows
listener.ora
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1)
(PROGRAM = extproc)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost.localdomain)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
tnsnames.ora
EXTPROC_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = PLSExtProc)
(PRESENTATION = RO)
If there is any thing wrong in the above configuration pls correct me.
cheers
RRKThat looks like the default configuration.
I can not test it here, but what I can see is, that your HOST=localhost.localdomain is not correct. Try it with the loopback interface 127.0.0.1 or give your FQDN and your hostname or your IP-Address.
If you look at your LISTENER configuration, there you have KEY=EXTPROC0 whereas in the tnsnames.ora file you have KEY=EXTPROC, so this doesn't match.
Just to name the two most obvious anomalies. -
Hi All
I have a question. How I can to return two or more values from external routines?
Have somebody any examples?
I have to return several values from function.
I C I have:
struct kolory
long int R;
long int G;
long int B;
struct kolory test()
struct kolory k;
k.R=10;
k.G=20;
k.B=15;
return k;
Thanks,
Krzysiekif you have fewer parameters, one easier way would be to pass them as OUT parameters from your PL/SQL
and make them as pointers in your C function. Inside the C function then assign values to those pointer
variables (after derefrencing). -
Extproc crashes when calling external routine
Can anyone point me to documentation on the causes of extproc.exe crashing when trying to invoke an external procedure? The standard documentation set isn't too helpful for debugging such a problem.
I have been able to call one external procedure. With two others, I always get an extproc crash with (I believe) an access violation.
The routines I am trying to call are 3rd-party, so I do not have the ability to view their source, though I do have the list of parameters and the sizes and types.
What I am hoping to find somewhere is a list of the kinds of things that cause extproc to crash so I can see if any of them are likely culprits in my situation.
Thanks,
Bruce MerkleHave you tried calling into the dll that CVI calls directly from TestStand? I am curious to know if this also crashes.
I am also curious to know if there are any path references in the dll that is called by the CVI program. If so are they relative, or absolute paths?
I ask because one of the possibilities is that relative paths are being used to specify a path from the location of the code that is called, and they are not working because the current working directory is being specified by TestStand, and the paths are not relative to the working directory given by TestStand.
Jensen
National Instruments
Applications Engineer -
External Routines & C++
Hi,
I'm trying to get an External procedure working with PL/SQL.
I notice in the example in ORACLE_HOME/RDBMS/extproc/
works fine for c, however if I recompile
the exact same code as a cpp file I get the
follwing error when trying to call the procedure:
ORA-06521: PL/SQL: Error mapping function
ORA-06522: Unable to load symbol from DLL
ORA-06512: at "SAMPLE.PLS_MAX", line 0
ORA-06512: at "SAMPLE.USEIT", line 8
ORA-06512: at line 2
is there any way to get external procedures working with C++?
Thanks for your time,
Cathalit depends on the type of linking performed.
if you do dynamic linking, then any additional libraries (DLLs) accessed by your program (apart from Windows DLLs and Oracle
libraries) need to be available on the server. -
How to call external Perl routines from Pl/SQL - Urgent
Available software in the Test Environment:
1. Sun Unix 2.8
2. Oracle 8.1.7 ( 8i)
3. Perl 5
Iam trying to call/execute perl scripts from PL/SQL using the DEMO_RDBMS.mk. I am able to call C scripts from PL/SQL, but actually want to call Perl scripts.
The steps followed for for C are -
1. Create and compile a simple C program to execute a unix command (eg., touch a file).
2. Make a shared library of the above compiled program (object), i.e., load the compiled object module into a dynamic load library.
3. Declare the above library in Oracle using SQL*Plus.
4. Define a PL/SQL function or procedure to call the external routine.
5. Test the external routine.
The above steps run good for a C program, but step 2 fails when run for a Perl script.
When I tried to use the following command for step 2 -
make -f $ORACLE_HOME/rdbms/demo/demo_rdbms.mk extproc_callback \
SHARED_LIBNAME=cmd_lib.so \
OBJS=tst_cmd.pl
got the following error -
ld: fatal: file tst_cmd.pl: unknown file type.
ld: fatal: File processing errors. No output written t cmd_lib.so
*** Error code 1
This gives me an indication that demo_rdbms.mk does not understand/interpret Perl scripts. Going through the demo_rdbms.mk suggests the same.
My questions is - How do we call external Perl scripts/routines from PL/SQL ??
Do I have to get a different version of "demo_rdbms.mk" ?
PS: The perl scripts used above (tst_cmd.pl) is error free and works as intended in the unix environment.Iam trying to call/execute perl scripts from PL/SQL using the DEMO_RDBMS.mk. I am able to call C scripts from PL/SQL, but actually want to call Perl scripts. Well, C is a "compiler" language and Perl is interpreted. In a sense, C is not "scripts".
When I tried to use the following command for step 2 -
make -f $ORACLE_HOME/rdbms/demo/demo_rdbms.mk extproc_callback \
SHARED_LIBNAME=cmd_lib.so \
OBJS=tst_cmd.pl
got the following error -
ld: fatal: file tst_cmd.pl: unknown file type.
ld: fatal: File processing errors. No output written t cmd_lib.soI guess this compiles an extproc "stub" with your object file, generating an external procedure. So the object file really needs to be an object file :-)
My questions is - How do we call external Perl scripts/routines from PL/SQL ??I'd guess you need an embedded Perl interpreter in the external procedure.
Not much help though I'm afraid :-/
Cheers
Fredrik -
How to pass a structure in PL/SQL external proc.
This is for educational purpose only. I am trying to implement kernel32.dll and shell32.dll in PL/SQL using external proc. Everything is working fine, except When there is a structure in OUT parameter.
My database version.
SQL> SELECT * FROM v$version;
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for 32-bit Windows: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - ProductionI have set up the listner.ora and tnsnames.ora and written a package called dbms_kernel32sb.
There are 9 program units.
1. CreateFile -- working fine
2. CloseFile -- working fine
3. GetSize -- working fine
4. FindFirstFile -- NOT working, because one OUT parameter has the structure type WIN32_FIND_DATA.
5. GetFileTime -- NOT working, because one OUT parameter has the structure type FILETIME
6. GetDiskFreeSpace -- working fine
7. GetDriveType -- working fine.
8. GetLastError -- working fine
9. ExecuteCommand -- working fine.
Here is the package specification:
CREATE OR REPLACE PACKAGE dbms_kernel32sb AS
Name: dbms_kernel32sb.pks
Author: Saubhik Banerjee
Date: 24th Jan 2011
Version: 1.0
Comment: This package is to implement some functionality from kernel32.dll.
Usng extproc
OPEN_EXISTING_FILE CONSTANT PLS_INTEGER :=3;
FILE_ATTRIBUTE_NORMAL CONSTANT PLS_INTEGER :=128;
DISABLE_FILE_SHARE_MODE CONSTANT PLS_INTEGER :=0;
NO_FILE_SECURITY_ATTRIBUTE CONSTANT PLS_INTEGER :=0;
NO_TEMPLATE_FILE CONSTANT PLS_INTEGER :=0;
GENERIC_FILE_ACCESS CONSTANT PLS_INTEGER :=0;
FILE_SIZE_HIGH CONSTANT PLS_INTEGER :=400000000;
EXECUTE_FILE CONSTANT VARCHAR2(4):='open';
PRINT_FILE CONSTANT VARCHAR2(5):='print';
NO_PARAMATER CONSTANT VARCHAR2(2):=' ';
FUNCTION CreateFile(pi_FileName VARCHAR2 --1, File name
,pi_DesiredAccess BINARY_INTEGER --2, Type of access required (read/write ect)
,pi_ShareMode BINARY_INTEGER --3, share mode
,pi_SecurityAttributes BINARY_INTEGER --4, securoty attribute
,pi_CreationDisposition BINARY_INTEGER --5, open existing, create new etc
,pi_FlagsAndAttributes BINARY_INTEGER --6, File attribute- normal
,pi_TemplateFile BINARY_INTEGER) --Not required.
Return BINARY_INTEGER;
FUNCTION CloseFile (pi_FileHandle BINARY_INTEGER)
Return BINARY_INTEGER;
FUNCTION GetSize (pi_FileHandle BINARY_INTEGER,
pio_FileSizeHigh IN OUT BINARY_INTEGER)
RETURN BINARY_INTEGER;
FUNCTION FindFirstFile ( pi_FileName VARCHAR2
,pio_Win32_Find_data OUT
WIN32_FIND_DATA
RETURN BINARY_INTEGER;
FUNCTION GetFileTime ( pi_FileHandle BINARY_INTEGER
,pio_FileCreationTime IN OUT FILETIME
,pio_LastAccessTime IN OUT FILETIME
,pio_LastWriteTime IN OUT FILETIME
RETURN BINARY_INTEGER;
FUNCTION GetDiskFreeSpace ( pi_RootPathName VARCHAR2
,pio_SectorsPerCluster OUT BINARY_INTEGER
,pio_BytesPerSector OUT BINARY_INTEGER
,pio_NumberOfFreeClusters OUT BINARY_INTEGER
,pio_TotalNumberOfClusters OUT BINARY_INTEGER
RETURN BINARY_INTEGER;
FUNCTION GetDriveType( pi_driveLetter VARCHAR2) RETURN VARCHAR2;
FUNCTION GetLastError RETURN BINARY_INTEGER;
FUNCTION ExecuteCommand ( pi_OperationType VARCHAR2
,pi_FileName VARCHAR2
,pi_Parameters VARCHAR2
,pi_DefaultDirectory VARCHAR2
RETURN VARCHAR2;
END dbms_kernel32sb;
Here is the package body:
CREATE OR REPLACE PACKAGE BODY dbms_kernel32sb AS
/* Name: dbms_kernel32sb.pkb
Author: Saubhik Banerjee
Date: 24th Jan 2011
Version: 1.0
Comment: This package is to implement some functionality from kernel32.dll.
Usng extproc
FUNCTION
CreateFile( pi_FileName VARCHAR2 --1
, pi_DesiredAccess BINARY_INTEGER --2
, pi_ShareMode BINARY_INTEGER --3
, pi_SecurityAttributes BINARY_INTEGER --4
, pi_CreationDisposition BINARY_INTEGER --5
, pi_FlagsAndAttributes BINARY_INTEGER --6
, pi_TemplateFile BINARY_INTEGER) --7
Return BINARY_INTEGER IS EXTERNAL LIBRARY kernel32 Name "CreateFileA"
PARAMETERS( pi_FileName STRING
, pi_DesiredAccess long
, pi_ShareMode long
, pi_SecurityAttributes long
, pi_CreationDisposition long
, pi_FlagsAndAttributes long
, pi_TemplateFile long
, return long);
FUNCTION CloseFile (pi_FileHandle BINARY_INTEGER)
Return BINARY_INTEGER
IS EXTERNAL
LIBRARY kernel32 Name "CloseHandle"
PARAMETERS (pi_FileHandle long, return long);
FUNCTION GetSize (pi_FileHandle BINARY_INTEGER,
pio_FileSizeHigh IN OUT BINARY_INTEGER)
RETURN BINARY_INTEGER
IS EXTERNAL
LIBRARY kernel32 NAME "GetFileSize"
PARAMETERS (pi_FileHandle long, pio_FileSizeHigh long, return long );
FUNCTION GetFileTime ( pi_FileHandle BINARY_INTEGER
,pio_FileCreationTime IN OUT FILETIME
,pio_LastAccessTime IN OUT FILETIME
,pio_LastWriteTime IN OUT FILETIME
RETURN BINARY_INTEGER
IS EXTERNAL
LIBRARY kernel32 NAME "GetFileTime"
WITH CONTEXT
PARAMETERS ( CONTEXT,
pi_FileHandle long
, pio_FileCreationTime OCIColl
, pio_FileCreationTime INDICATOR SHORT
, pio_LastAccessTime OCIColl
, pio_LastAccessTime INDICATOR SHORT
, pio_LastWriteTime OCIColl
, pio_LastWriteTime INDICATOR SHORT
, return long );
FUNCTION FindFirstFile ( pi_FileName VARCHAR2
,pio_Win32_Find_data OUT
WIN32_FIND_DATA
RETURN BINARY_INTEGER
IS EXTERNAL
LIBRARY kernel32 NAME "FindFirstFileA"
--WITH CONTEXT
PARAMETERS
( --CONTEXT,
pi_FileName STRING--, pi_FileName INDICATOR SHORT
, pio_Win32_Find_data BY REFERENCE OCIColl--,pio_Win32_Find_data INDICATOR long
, return long );
FUNCTION GetDiskFreeSpace ( pi_RootPathName VARCHAR2
,pio_SectorsPerCluster OUT BINARY_INTEGER
,pio_BytesPerSector OUT BINARY_INTEGER
,pio_NumberOfFreeClusters OUT BINARY_INTEGER
,pio_TotalNumberOfClusters OUT BINARY_INTEGER
RETURN BINARY_INTEGER
IS EXTERNAL
LIBRARY kernel32 NAME "GetDiskFreeSpaceA"
PARAMETERS ( pi_RootPathName STRING
, pio_SectorsPerCluster BY REFERENCE long
, pio_BytesPerSector BY REFERENCE long
, pio_NumberOfFreeClusters BY REFERENCE long
, pio_TotalNumberOfClusters BY REFERENCE long
, return long );
FUNCTION GetDriveTypeA( pi_driveLetter VARCHAR2) RETURN BINARY_INTEGER
IS EXTERNAL
LIBRARY kernel32 NAME "GetDriveTypeA"
PARAMETERS (pi_driveLetter STRING, RETURN long);
FUNCTION GetDriveType( pi_driveLetter VARCHAR2) RETURN VARCHAR2 IS
BEGIN
CASE GetDriveTypeA(pi_driveLetter)
WHEN 2 THEN RETURN 'Removable';
WHEN 3 THEN RETURN 'Drive Fixed';
WHEN 4 THEN RETURN 'Remote';
WHEN 5 THEN RETURN 'Cd-Rom';
WHEN 6 THEN RETURN 'Ram disk';
ELSE RETURN 'Unrecognized';
END CASE;
END;
FUNCTION GetLastError RETURN BINARY_INTEGER
IS EXTERNAL
LIBRARY kernel32 NAME "GetLastError"
PARAMETERS (return long);
FUNCTION ShellExecute( pi_Hwnd BINARY_INTEGER
,pi_Operation VARCHAR2
,pi_FileName VARCHAR2
,pi_Parameters VARCHAR2
,pi_DefaultDirectory VARCHAR2
,pi_ShowCmd BINARY_INTEGER
) RETURN BINARY_INTEGER
IS EXTERNAL
LIBRARY SHELL32 NAME "ShellExecuteA"
PARAMETERS (pi_Hwnd long,pi_Operation STRING,pi_FileName STRING
,pi_Parameters STRING,pi_DefaultDirectory STRING
,pi_ShowCmd long, return long
FUNCTION ExecuteCommand ( pi_OperationType VARCHAR2
,pi_FileName VARCHAR2
,pi_Parameters VARCHAR2
,pi_DefaultDirectory VARCHAR2
RETURN VARCHAR2 IS
v_return_val BINARY_INTEGER;
BEGIN
v_return_val:= ShellExecute(0,pi_OperationType
,pi_FileName,pi_Parameters
,pi_DefaultDirectory,0
IF v_return_val <=32 THEN
RETURN 'Error!';
ELSE RETURN 'Success!';
END IF;
END;
END dbms_kernel32sb;
Now the working demos:
SQL> SET SERVEROUT ON
SQL> /* Demo I:- How to obtain file size */
SQL> DECLARE
2 v_FileSize BINARY_INTEGER;
3 v_FileSizeHigh PLS_INTEGER;
4 v_FileHandle BINARY_INTEGER;
5 v_filename VARCHAR2(500) :='C:\test2.csv';
6 v_dummy BINARY_INTEGER;
7 BEGIN
8 v_FileSizeHigh := DBMS_KERNEL32SB.FILE_SIZE_HIGH;
9 v_FileHandle:=DBMS_KERNEL32SB.CreateFile(v_filename -- File name
10 ,DBMS_KERNEL32SB.GENERIC_FILE_ACCESS
11 ,DBMS_KERNEL32SB.DISABLE_FILE_SHARE_MODE
12 ,DBMS_KERNEL32SB.NO_FILE_SECURITY_ATTRIBUT
13 ,DBMS_KERNEL32SB.OPEN_EXISTING_FILE
14 ,DBMS_KERNEL32SB.FILE_ATTRIBUTE_NORMAL
15 ,DBMS_KERNEL32SB.NO_TEMPLATE_FILE);
16 v_FileSize := DBMS_KERNEL32SB.Getsize(v_FileHandle, v_FileSizeHigh)
17 DBMS_OUTPUT.put_line('File Size in Bytes: ' ||v_FileSize);
18 v_dummy:=DBMS_KERNEL32SB.CloseFile(v_FileHandle);
19 END;
20 /
File Size in Bytes: 61
PL/SQL procedure successfully completed.
SQL>
SQL> /* Demo II:- How to find free disk space */
SQL> DECLARE
2 v_rootpath VARCHAR2(500) :='C:\';
3 v_dummy BINARY_INTEGER;
4 v_sectorspercluster BINARY_INTEGER;
5 v_bytespersector BINARY_INTEGER;
6 v_numberoffreeclusters BINARY_INTEGER;
7 v_totalnumberofclusters BINARY_INTEGER;
8 v_freespace NUMBER;
9 v_totalspace NUMBER;
10 BEGIN
11 v_dummy:=DBMS_KERNEL32SB.GetDiskFreeSpace(v_rootpath
12 ,v_sectorspercluster
13 ,v_bytespersector
14 ,v_numberoffreeclusters
15 ,v_totalnumberofclusters
16 );
17
18 DBMS_OUTPUT.put_line('Sector pre Cluster: ' ||v_sectorspercluster);
19 DBMS_OUTPUT.put_line('Bytes per sector: ' ||v_bytespersector);
20 DBMS_OUTPUT.put_line('Number Of Free Clusters: ' ||v_numberoffreeclusters);
21 DBMS_OUTPUT.put_line('Total Number Of Clusters: ' ||v_totalnumberofclusters);
22 v_freespace:=v_numberoffreeclusters/1024/1024/1024;
23 v_freespace:=ROUND(v_freespace*v_sectorspercluster*v_bytespersector,3);
24 v_totalspace:=v_totalnumberofclusters/1024/1024/1024;
25 v_totalspace:=ROUND(v_totalspace*v_sectorspercluster*v_bytespersector,3);
26 DBMS_OUTPUT.put_line('Total Space (GB):' ||v_totalspace);
27 DBMS_OUTPUT.put_line('Total number of Free space (GB): '||v_freespace );
28 END;
29 /
Sector pre Cluster: 8
Bytes per sector: 512
Number Of Free Clusters: 739477
Total Number Of Clusters: 9765622
Total Space (GB):37.253
Total number of Free space (GB): 2.821
PL/SQL procedure successfully completed.
SQL>
SQL> /* Demo IV:- How to get drive type*/
SQL> SELECT dbms_kernel32sb.GetDriveType('C:\') FROM dual;
DBMS_KERNEL32SB.GETDRIVETYPE('C:\')
Drive Fixed
SQL> SELECT dbms_kernel32sb.GetDriveType('D:\') FROM dual;
DBMS_KERNEL32SB.GETDRIVETYPE('D:\')
Cd-Rom
SQL> SELECT dbms_kernel32sb.GetDriveType('E:\') FROM dual;
DBMS_KERNEL32SB.GETDRIVETYPE('E:\')
Unrecognized
SQL>
SQL> /* Demo V:- How to execute an Operating System Command*/
SQL> DECLARE
2 v_FileToExecute VARCHAR2(20):='test.bat';
3 v_Parameter VARCHAR2(20):='test1.csv';--dbms_kernel32sb.NO_PARAMATER
4 v_DefaultDirectory VARCHAR2(20):='C:\';
5 v_ReturnValue VARCHAR2(20);
6 BEGIN
7 v_ReturnValue:=dbms_kernel32sb.ExecuteCommand(dbms_kernel32sb.EXECUTE_FILE
8 ,v_FileToExecute
9 ,v_Parameter
10 ,v_DefaultDirectory
11 );
12 DBMS_OUTPUT.put_line('Status: '||v_ReturnValue);
13 END;
14 /
Status: Success!
PL/SQL procedure successfully completed.
SQL> Now the sub programs with structures are NOT getting called successfully.
SQL> /* Demo III:- How to obtain file time */
SQL> DECLARE
2 v_FileHandle BINARY_INTEGER;
3 v_filename VARCHAR2(500) :='C:\test2.csv';
4 v_dummy BINARY_INTEGER;
5 v_filecreationtime FILETIME;
6 v_lastaccesstime FILETIME;
7 v_lastwritetime FILETIME;
8 v_err BINARY_INTEGER;
9 BEGIN
10 v_FileHandle:=DBMS_KERNEL32SB.CreateFile(v_filename -- File name
11 ,DBMS_KERNEL32SB.GENERIC_FILE_ACCESS
12 ,DBMS_KERNEL32SB.DISABLE_FILE_SHARE_MODE
13 ,DBMS_KERNEL32SB.NO_FILE_SECURITY_ATTRIBUTE
14 ,DBMS_KERNEL32SB.OPEN_EXISTING_FILE
15 ,DBMS_KERNEL32SB.FILE_ATTRIBUTE_NORMAL
16 ,DBMS_KERNEL32SB.NO_TEMPLATE_FILE);
17 v_dummy := DBMS_KERNEL32SB.GetFileTime( v_FileHandle
18 ,v_filecreationtime
19 ,v_lastaccesstime
20 ,v_lastwritetime
21 );
22 v_err:=DBMS_KERNEL32SB.GetLastError;
23 DBMS_OUTPUT.put_line('File Size in Bytes: ' ||v_dummy);
24 DBMS_OUTPUT.put_line('Error:'||v_err);
25 v_dummy:=DBMS_KERNEL32SB.CloseFile(v_FileHandle);
26 END;
27 /
File Size in Bytes: 0
Error:203
PL/SQL procedure successfully completed.
SQL> So, I have noticed that, Where ever a STRUCTURE is involved in external routine, there is a problem. I want to know, How to implement functions with STRUCTURE as OUT parameter.
Forgot to mention: This is my FILETIME object which corresponds to FILETIME structure of win32.
CREATE OR REPLACE TYPE FILETIME_rec IS OBJECT
( LowDateTime NUMBER
,HighDateTime NUMBER
CREATE OR REPLACE TYPE FILETIME IS TABLE OF FILETIME_rec;Edited by: Saubhik on Feb 1, 2011 4:15 PMSaubhik wrote:
This is for educational purpose only. I am trying to implement kernel32.dll and shell32.dll in PL/SQL using external proc. Interesting. Familiar with the Wn32 API, but do not run Oracle on Windows and never looked at this aspect of integration.
So, I have noticed that, Where ever a STRUCTURE is involved in external routine, there is a problem. I want to know, How to implement functions with STRUCTURE as OUT parameter.
Forgot to mention: This is my FILETIME object which corresponds to FILETIME structure of win32.The problem is that this passes the parameter by reference and not value. In a vanilla C/C++/Delphi program, you will create a variable of that struct and then pass a long pointer to that variable when making the API call. That pointer will be dereferenced and the memory it points to, populated. This is not a problem as the underlying DLL you call that does this, uses your process's data segment.
Extproc is different. In order to protect the integrity of the database server process, an external call is done by a "proxy" process. It acts as the interface between your PL/SQL code and the actual external call.
In this case, this "proxy" process will be doing the implicit LoadLibrary() call to load kernel32.dll interface - and the DLL will expect to dereference and access this process's memory struct to populate it. This "proxy" process in turn needs to know that despite it calling the interface by reference, it needs to return that parameter to PL/SQL by value - as your PL/SQL code cannot dereference a pointer passed back by that "proxy" process and access its memory to gain access to that struct.
In basic terms - that argument is a 32 bit number containing a pointer. That is what the "proxy" process needs to pass to the interface call. Your code is passing a struct and not a pointer, right?
And that is the basic problem I believe. How to address this.. not sure. You can have your own DLL as interface that does not use pointers but expect arguments to be passed by value. But this will suck as you then need to include a custom DLL to deploy and have PL/SQL call that, instead of simply accessing and calling the native kernel interface.
Doubt that many Win32 programmers with OCI (Oracle Call Interface) frequents this forum. So perhaps this is not the best place to ask. I would be hitting Metalink (support.oracle.com) search function in your sho3s though as there should be support notes dealing with this subject matter. -
I try make the external routine writen in C. Function writen in C and stored in D:\extproc\zzz1.dll
I make the library and function
CREATE or replace LIBRARY externProcedures AS 'D:\extproc\zzz1.dll'
create or replace function pls_max(x binary_integer)
return binary_integer as
external library externProcedures
name "find_max" language C parameters (x long);
Then i execute SQl: select pls_max(10) from dual;
And got the error
ERROR at line 1:
ORA-06521: PL/SQL: Error mapping function
ORA-06522: Unable to load symbol from DLL
Anyone have any idea how to solve this problem? Iv heard about using the following code
#ifdef __cplusplus
extern "C" {
#endif
and
#ifdef __cplusplus
#endif
around the external function. But to be honest this confuses me more. What external function and how does it go around it?
For the sake of my sanity, does anyone have any ideas?
Kind Regards
Richard Claytonhi i am ashutosh i am too having a similar kind of problem
this is what i did
MY CPP FILE
# include <conio.h>
# include <stdio.h>
#include "dlltest.h"
#define MAXMODULE 50
char module[MAXMODULE];
extern "C" __declspec(dllexport) int NumberList()
{ //GetModuleFileName(NULL, (LPTSTR)module, MAXMODULE);
printf("\n\nThis function was called from ");
printf("NumberList(): ");
for(int i=0; i<10; i++)
{ printf("%d ",i);
printf("\n\n");
return int(10);
extern "C" __declspec(dllexport) int LetterList(int x)
{ //GetModuleFileName(NULL, (LPTSTR)module, MAXMODULE);
printf("\n\nThis function was called from ");
printf("LetterList(): ");
for(int i=0; i<26; i++)
{ printf("%c ",char(97 + i));
} printf("\n\n");
return 10;
HEADER FILE
#ifdef __cplusplus
extern "C" {
#endif
extern "C" __declspec(dllexport) int NumberList();
//int NumberList();
#ifdef __cplusplus
#endif
#ifndef DLLTESTH_
#define DLLTESTH_
#include <iostream.h>
#include <stdio.h>
#include <windows.h>
extern "C" __declspec(dllexport) int LetterList(int);
#endif
NOW I WANT TO CALL THE NumberList FUNCTION IN MYDLL.DLL FILE FROM ORACLE
SO THIS IS WHT I DID
CREATE OR REPLACE LIBRARY nt_kernel
AS
--'c:\winnt\system32\MYDLL.dll';
'E:\DLL\MyDLL\Debug\MYDLL.dll';
CREATE OR REPLACE PACKAGE disk_util
AS
FUNCTION get_disk_free_space
-- (X OUT PLS_INTEGER)
RETURN PLS_INTEGER;
PRAGMA RESTRICT_REFERENCES (get_disk_free_space,WNPS, RNPS, WNDS, RNDS);
END disk_util;
CREATE OR REPLACE PACKAGE BODY disk_util
AS
FUNCTION get_disk_free_space
--(X OUT PLS_INTEGER)
RETURN PLS_INTEGER
IS EXTERNAL
LIBRARY nt_kernel -- our library (defined previously)
NAME "NumberList" -- name of function in kernel32.dll
LANGUAGE C -- external routine is written in C
CALLING STANDARD PASCAL -- uses Pascal parameter convention
PARAMETERS -- map PL/SQL to C parameters by
-- position
(RETURN int);
END disk_util;
CREATE OR REPLACE PROCEDURE TEMP
AS
lX PLS_INTEGER;
return_code PLS_INTEGER;
BEGIN
return_code := disk_util.get_disk_free_space ();
DBMS_OUTPUT.PUT_LINE('free disk space, megabytes = ' || to_char(return_code));
END;
*********WHEN I EXEC TEMP THE FOLLOWING ERROR SHOWED UP
SQL> EXEC TEMP;
BEGIN TEMP; END;
ERROR at line 1:
ORA-06521: PL/SQL: Error mapping function
ORA-06522: Unable to load symbol from DLL
ORA-06512: at "MNE.DISK_UTIL", line 0
ORA-06512: at "MNE.TEMP", line 6
ORA-06512: at line 1 -
Need help for QCI ASTM routines
Hello Friends,
Presently I am setting up the QCI config in our test server. I have configured the necessary settings for the Conversion group and the reading group. Now when I am testing the results using the O3QCITEST transaction, I am getting an error message that "Quantity Conversion Interface: No response from external programs"
In the help of this error message it is suggested to run report ROIB_QCI_CALL_TEST (T-code O3D2) to test the communication with external routines. When I checked it is actually getting failed, so can anybody suggest where I need to check for these routines.
What do I need to check with the BASIS guys in order to ensure that these routines are available and QCI calculations are happening?
thanks,
RiteshRitesh
Assuming that you are using API - C routine for QCI.
Please let me know if you are using ASTM(old version) or ASTM_2004 (latest version) ?
In case you are using old command, i.e. astm
Please check at operating system level, following command ;
ASTM <table1> <density> <temp>
for ex: ASTM tab24b 0.000642 15.5
This should provide you result at Operating system level. Only then you can expect O3QCITEST to provide result.
Let me know.
Regards
Nilesh Thakkar -
Calling external C code from the database
Hi,
We have an external routine written in C which we want to reuse. I have run this using external procedure call but as expected extproc processing is very slow. The routine cannot be rewritten, it is a "black box" component. We have considered wrapping the call to C in a Java procedure using JNI and installing the java inside the database to run inside the oracle jvm. Does anyone know if this will work or has any experience of using JNI inside the database? Is this supported by Oracle? Does anyone have any ideas/advice for tuning extproc calls or other alternatives to suggest for calling C from inside the database.
ThanksThanks for the advice. I did notice the support comment in the documentation - pretty much kills that idea then! Bulk processing might be difficult. The external procedure works on two values, one taken from the environment and one from a value embedded in each row of a table...the function is called once for each row and returns a value which i then use within a context and drives visibility, or not, of the row through Virtual Private Database configuration. So when an operator runs "Select * from a_table" the VPD adds in "and/where this_row_is_visible". Both the row value and operator environment value are updateable in real time so I cannot "process" the data first. Sounds like I need to set expectations here!
Thanks -
Dear All,
Need your ehlp.
As I understand that QCI calculation can happen in two ways i.e. internal or external.
If we select internal then we need to run SE38 for program " ROIB_QCI_SET_OIB01_INT_EXT " and select the internal QCI conversion.
If we select external QCI calculation then select button " Call API codes " and use API or Quantity ware routines from RFC server and do the calculations.
Pls. advise if I my understanding is correct .
Regards,
VijayDear Vijay,
Report ROIB_QCI_SET_OIB01_INT_EXT has been delivered by SAP so that you can turn off the external call of the SAP template conversion groups. This is typically required if you have not yet decided if you will utilize the API c-codes or e.g. the QuantityWare BCP solution.
This way, you can run the SAP installation test witout having made that decision. Important to note that the calculation results of the approx. 16 SAP conversion groups will then deliver dummy results.
If you then decide to utilize e.g. QuantityWare BCP, Quantityware delivers its own full blown test suite which performs a second functional correctness test of the QuantityWare BCP delivery:
http://www.quantityware.com/_data/BCP10A_Project_Assessment_and_Implementation_Guidelines_SP12.pdf
In Chapter 3 of this document, the installation test is described. Approx. 300 000 automated quantity conversions are tested and compared with the 300 000 validated examples.
After these two tests (SAP installation w/o external routines and QuantityWare BCP 10A installation test you are done and you can select from the more then 350 QuantityWare template conversion groups.
If you decide to utilize a legacy API c-code installation, you have to reset the SAP template conversion groups using ROIB_QCI_SET_OIB01_INT_EXT and re-run the SAP installation test. Then about 20 simple test examples are again executed, but still without functional correctness check of the calculation result. These examples only check if the API c-codes deliver a result.
I hope this helps,
Kind regards,
Markus -
Difference between sy-repid and sy-cprog
Hi all,
in a function module call I want to pass the calling report's name as an import parameter. I want to do this dynamically so that the 'call function ....' code can be copied to any report.
I found two SY-fields, sy-repid and sy-cprog. So far both always contain the running report's name.
Is there an important difference between the two? Is one perhaps deprecated?
Regards,
EricHi Eric,
SY-REPID:
Name of the current ABAP program. For externally-called procedures, it is the name of the main program of the procedure. If you pass SY-REPID as an actual parameter to an external procedure, the formal parameter does not contain the name of the caller, but that of the main program of the procedure. To avoid this, assign SY-REPID to an auxiliary variable and use that in the call, or use the system field SY-CPROG.
SY-CPROG:
The name of the calling program in an external routine, otherwise the name of the current program.
For more information, please check this links.
http://help.sap.com/saphelp_nw2004s/helpdata/en/7b/fb96c8882811d295a90000e8353423/content.htm
http://help.sap.com/saphelp_46c/helpdata/en/7b/fb96c8882811d295a90000e8353423/content.htm
Hope this will help.
Regards,
Ferry Lianto -
How Can I Disable "Live" Web Links in a PDF
I have a pdf which is assembled from a variety of original documents, including one document that has a dozen or so "live" url links to websites. I didn't create the document in question, and I don't have access to the original word processing file.
I need to upload the whole document to a website that will not accept pdfs with live links. (It's a filing in a legal action, and the website is operated by a court.) The website support people have told me to remove or disable the links.
This ought to be easy, but I can't figure it out. I can't edit the source document to deactivate the links, (i) becasue I don't have it, and (ii) because it's a part of the record that shouldn't be modified without some form of formal process.
I tried scanning the pages with the links, with the thought that I would replace the original pages with scanned pages. But the court requires text searchable documents, and the OCR process identified the links as urls and created live links.
If there's a basic setting that turns deactivates web links in the text, I haven't found it.
Grateful for all suggestions.
TomThanks for the thought, but the document in question has already been reviewed by the technical department of the court's website help desk. They have identified the website addresses in the text as the reason why their system won't accept it and directed me to remove them. They refer to the addresses as "hyperlinks," which led me to believe that there was a separate link object involved.
However, from what I've learned here tonight, the problem is Acrobat's default behavior in parsing a text string that begins with "http:"
There are a number of ways to handle the problem, all of which involve a little bit of busy work, but it's not a big deal.
It's just it would have been easier if there were some preference I could enable before re-saving the document that did the trick. Now that I think about it, a programmer could probably create an external routine (I assume such things exist for pdf files?) that would "mask" the http string from the parsing engine, or otherwise instruct the application not to generate a live link. But such a routine itself would probably be rejected as as "code which may cause an external action," and there's probably no way to distinguish "good" external routines from malware.
Cheers,
Tom -
How to print check boxes in output using alv
send me replly immediately
hi
Program Name: ALV ON SECONDARY LISTS Creation: 02/01/2007*
SAP Name : YH634_0102007_ALV_LIST Application: *
Author : P.V.D.Veeresh Babu Type: 1 *
Description : This program is used to display secondary lists using *
ALV. *
Inputs: *
Tables: *
SPFLI - Flight information *
SFLIGHT - Flight *
SBOOK - Flight booking details *
Select options: *
N/A *
Parameters: *
NO *
Outputs: secondary lists with ALV *
External Routines *
Function Modules: *
REUSE_ALV_LIST_DISPLAY *
Transactions : No *
Programs : No *
Return Codes: No *
Ammendments: *
Programmer Date Req. # Action *
================ ========== ====== ==============================*
type-pools: slis.
*" Data declarations...................................................
Data declaration of the structure to hold layout details *
data:
fs_layout type slis_layout_alv.
*" Data declarations...................................................
Data declaration of the structure to hold spfli details *
data: begin of fs_spfli,
color(4) type c, " Color
check type c. " Check box
include structure spfli. " Spfli
data end of fs_spfli.
*" Data declarations...................................................
Data declaration of the structure to hold sflight details *
data:begin of fs_sflight,
color(4) type c, " Color
check type c. " Check box
include structure sflight. " Sflight
data end of fs_sflight.
*" Data declarations...................................................
Data declaration of the structure to hold sbook details *
data:
fs_sbook like sbook.
Internal table to hold list details *
data:
t_sbook like
standard table
of fs_sbook.
Internal table to hold list details *
data:
t_sflight like
standard table
of fs_sflight .
Internal table to hold spfli details *
data:
t_spfli like
standard table
of fs_spfli.
fs_layout-box_fieldname = 'CHECK'.
fs_layout-info_fieldname = 'COLOR'.
"........Retrieving basic list data containing spfli details......."
select *
from spfli
into corresponding fields of table t_spfli.
if sy-subrc ne 0.
message text-001 type 'I'.
endif. " IF SY-SUBRC NE 0
".................Calling function module for ALV..................."
call function 'REUSE_ALV_LIST_DISPLAY'
exporting
i_callback_program = sy-repid
i_callback_pf_status_set = 'STATUS1'
i_callback_user_command = 'USER_COMMAND1'
i_structure_name = 'SPFLI'
is_layout = fs_layout
tables
t_outtab = t_spfli
exceptions
program_error = 1
others = 2.
if sy-subrc <> 0.
message text-002 type 'I'.
endif. " IF SY-SUBRC NE 0
Form STATUS1 *
This subroutine gives pf-status for spfli list *
-->T_EXTAB excluding table *
form status1 using t_extab type slis_t_extab.
set pf-status 'STATUS1'.
endform. " STATUS1
Form USER_COMMAND1 *
This subroutine displays secondary list containing sflight details*
-->FS_UCOMM user command *
-->T_SELFIELD selfield *
form user_command1 using fs_ucomm type sy-ucomm
t_selfield type slis_selfield.
case fs_ucomm.
when 'SFLIGHT'.
perform display_list2.
endcase. " CASE FS_UCOMM
t_selfield-refresh = 'X'.
endform. " USER_COMMAND1
Form DISPLAY_LIST2 *
This subroutine displays sflight details on secondary list *
There are no interface parameters to be passed in this subroutine *
form display_list2 .
data lw_flag type i. " Flag
refresh t_sflight.
loop at t_spfli into fs_spfli.
if fs_spfli-check = 'X'.
"........Retrieving basic list data containing sflight details......."
select *
from sflight
appending corresponding fields of table t_sflight
where carrid eq fs_spfli-carrid
and connid eq fs_spfli-connid.
if sy-subrc eq 0.
lw_flag = 1.
endif. " IF SY-SUBRC EQ 0
FS_SPFLI-CHECK = '0'.
fs_spfli-color = 'C510'.
modify t_spfli from fs_spfli .
endif. " IF FS_SPFLI-CHECK EQ 'X'
endloop. " LOOP AT T_SPFLI INTO FS_SPFLI
if lw_flag eq 0.
message text-003 type 'E'.
endif. " IF LW_FLAG EQ 1
".................Calling function module for ALV..................."
call function 'REUSE_ALV_LIST_DISPLAY'
exporting
i_callback_program = sy-repid
i_callback_pf_status_set = 'STATUS2'
i_callback_user_command = 'USER_COMMAND2'
i_structure_name = 'SFLIGHT'
is_layout = fs_layout
tables
t_outtab = t_sflight
exceptions
program_error = 1
others = 2.
if sy-subrc <> 0.
message text-002 type 'I'.
endif. " IF SY-SUBRC NE 0
endform. " DISPLAY_LIST2
Form STATUS2 *
This subroutine gives pf-status for secondary list. *
-->T_EXTAB Excluding table *
form status2 using t_extab type slis_t_extab.
set pf-status 'STATUS2'.
endform. " STATUS2
Form USER_COMMAND2 *
This subroutine gives secondary list containing sbook details *
-->FS_UCOMM user command *
-->T_SELFIELD selfield *
form user_command2 using fs_ucomm type sy-ucomm
t_selfield type slis_selfield.
case fs_ucomm.
when 'SBOOK'.
perform display_list3.
endcase. " CASE FS_UCOMM
t_selfield-refresh = 'X'.
endform. " USER_COMMAND2
Form DISPLAY_LIST3 *
This subroutine displays sbook details on secondary list *
There are no interface parameters to be passed in this subroutine *
form display_list3 .
data lw_flag type i. " Flag
refresh t_sbook.
loop at t_sflight into fs_sflight.
if fs_sflight-check eq 'X'.
"........Retrieving basic list data containing sbook details......."
select *
from sbook
appending corresponding fields of table t_sbook
where carrid eq fs_sflight-carrid
and connid eq fs_sflight-connid
and fldate eq fs_sflight-fldate.
if sy-subrc eq 0.
lw_flag = 1.
endif. " IF SY-SUBRC EQ 0
FS_SFLIGHT-CHECK = '0'.
fs_sflight-color = 'C910'.
modify t_sflight from fs_sflight.
endif. " IF FS_FLIGHT-CHECK EQ 'X'
endloop. " LOOP AT T_SFLIGHT INTO....
if lw_flag eq 0.
message text-004 type 'E'.
endif. " IF LW_FLAG EQ 1
".................Calling function module for ALV..................."
call function 'REUSE_ALV_LIST_DISPLAY'
exporting
i_structure_name = 'SBOOK'
is_layout = fs_layout
tables
t_outtab = t_sbook
exceptions
program_error = 1
others = 2.
if sy-subrc <> 0.
message text-002 type 'I'.
endif. " IF SY-SUBRC NE 0
endform. " DISPLAY_LIST3
regards,
veeresh
null -
Check/uncheck record results on more than one step at a time
I have one hundred plus sequence files and several thousand steps total. Checking and un-checking record results one step at a time takes a long time. I'd like to be able to select several steps at a time then check or un check the "Record Results" option for all those steps at once. How do I do this? I'm using TestStand 2.0
Hi Kevin,
Thanks for contacting National Instruments.
Do you want to disable result recording for ALL sequences on this station? If so, you can turn on this option in the TestStand sequence editor (Configure >> Station Options, turn ON checkbox "Disable result recording for all sequences").
However, if you only want to do this for selected sequence files, then Ray is correct - you would need to write an external routine that will automate this for you. Attached is a zipfile containing a VBScript that will iterate through one sequence file ("c:\test.seq") and change all steps (all sequences, including Main/Setup/Cleanup) to turn off "Record Results". It first saves a backup copy of the sequence file, makes the changes, then save
s the modified sequence file. You can enhance this script to work for more than one sequence file by using Microsoft's FileSystemObject.
The VBScript uses a DLL I created, which exposes the TestStand 2.0 Engine object as an ActiveX DLL. Before you can run the VBScript, you will need to register this DLL:
regsvr32 TSEngine.dll
Then, the VBScript can be executed just by double-clicking it. Hopefully this helps get you started toward creating an automated way of solving this problem!
David Mc.
National Instruments
Attachments:
ts2seqfiles.zip 4 KB
Maybe you are looking for
-
This is a little complicated. I have a Thinkpad T-60 (4GB) and a T-61p (8GB) Both machines have SATA drives partitioned in 3 (System, Images, Data) Originally, both had XP (the T-61p was RAM upgraded to 8 GB before upgrade (remember the $50 early-bir
-
What is the best option buy bigasoft converter or quicktime pro to translate mts files?
I have a MBP 2.66 core duo and a canon hf200 (with a transcend 16gb class6 sd card). I shot 90 minutes of footage and then tried the sd reader in the MBP, and even connected the camcorder via usb cable but the only files that are found are VLC or ra
-
Hi i am currently editing clips in premiere pro cc but everytime i go to change the speed not the duration of a clip it will not let me select it - also when i go to effect controls it will not let me select time mapping? please help
-
I'm using Messages app on my MBP, sending texts to my daughters who have iPhones. They both tell me that they often get duplicate messages, not all the time, but quite frequently. I can find no similarities or patters between when they get a duplic
-
Media de instalación acrobat 9
hola me gustaría saber donde puedo descargar la media de instalación de un acrobat 9 del que cuento con la licencia pero no con la media de instalación y de la version 10 tengo la media de instalacion pero no se donde viene la licencia