A script-enabled browser is required for this page to function properly.

ORA_FFI Example 2

Suppose you want to create an interface to the following C functions, which are located in the library C:\oralibs\imglib.dll:


void *get_image(char *imgkey)
void show_image(void *binimage, float iscale)

Assume that the function get_image uses a keyword argument to load image data, and then returns a generic pointer (that is, a pointer of unspecified type) to that binary data. You then pass the pointer and a scaling factor to show_image, which displays the image on the screen.

First, create a package specification that represents the library and defines the PL/SQL functions that you want to invoke:


PACKAGE imglib IS
 FUNCTION get_image(ikey IN OUT VARCHAR2) 
  RETURN ORA_FFI.POINTERTYPE; 
 PROCEDURE show_image(idata ORA_FFI.POINTERTYPE, 
 iscale NUMBER); 
END; /* package imglib */

The package body is defined below:


PACKAGE BODY imglib IS 
/* Declare the library and function handles. */ 
imglib_lhandle ORA_FFI.LIBHANDLETYPE; 
get_image_fhandle ORA_FFI.FUNCHANDLETYPE; 
show_image_fhandle ORA_FFI.FUNCHANDLETYPE; 


/* Create the PL/SQL function that will actually */ 
/* invoke the 'get_image' foreign function. */ 
FUNCTION ff_get_image(fhandle ORA_FFI.FUNCHANDLETYPE, 
ikey IN OUT VARCHAR2) 
RETURN ORA_FFI.FUNCHANDLETYPE; 
PRAGMA interface(C, ff_get_image, 11265); 


/* Create the 'get_image' PL/SQL function that is */ 

/* defined in the package spec. */ 
FUNCTION get_image(ikey IN OUT VARCHAR2)  
 RETURN ORA_FFI.POINTERTYPE IS 
 ptr ORA_FFI.POINTERTYPE; 
BEGIN 
 ptr.handle := ff_get_image(get_image_fhandle, ikey); 
 RETURN(ptr); 
END; /* function get_image */ 


/* Create the PL/SQL procedure that will actually */ 

/* invoke the 'show_image' foreign function. */ 
PROCEDURE ff_show_image(fhandle ORA_FFI.FUNCHANDLETYPE, 
idata ORA_FFI.HANDLETYPE, 
iscale NUMBER); 
PRAGMA interface(C, ff_show_image, 11265); 


/* Create the 'show_image' PL/SQL procedure that is */ 

/* defined in the package spec. */ 
PROCEDURE show_image(idata ORA_FFI.POINTERTYPE, 
iscale NUMBER) IS 
BEGIN 
  ff_show_image(show_image_fhandle, idata.handle, iscale); 
END; /* procedure show_image */ 


BEGIN /* package body imglib */ 
 /* Load the library. */ 
  imglib_lhandle := ORA_FFI.LOAD_LIBRARY 
  ('C:\oralibs\', 'imglib.dll');


/* Register the foreign functions. */ 
 get_image_fhandle := ORA_FFI.REGISTER_FUNCTION 
(imglib_lhandle, 'get_image', ORA_FFI.C_STD); 
show_image_fhandle := ORA_FFI.REGISTER_FUNCTION 
(imglib_lhandle, 'show_image', ORA_FFI.C_STD); 


/* Register the parameters. */ 
 ORA_FFI.REGISTER_PARAMETER(get_image_fhandle,ORA_FFI.C_CHAR_PTR);
 ORA_FFI.REGISTER_PARAMETER(show_image_fhandle, ORA_FFI.C_VOID_PTR); 
 ORA_FFI.REGISTER_PARAMETER(show_image_fhandle, ORA_FFI.C_FLOAT);


/* Register the return type ('get_image' only). */ 
 ORA_FFI.REGISTER_RETURN(get_image_fhandle, ORA_FFI.C_VOID_PTR); 

END; /* package body imglib */

To invoke the foreign functions, you would call the PL/SQL procedures defined in the package specification, as in the following example:


PROCEDURE display_image(keywrd IN OUT VARCHAR2) IS
 img_ptr ORA_FFI.POINTERTYPE;
  BEGIN
   img_ptr := imglib.get_image(keywrd);
   imglib.show_image(img_ptr, 2);
END; /* procedure display_image */

See also

About the ORA_FFI built-in package

ORA_FFI built-in package

ORA_FFI built-in package examples