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

ORA_FFI.Example 3

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 (i.e., 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.handleType; 
    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 */