Home » Developer & Programmer » Forms » ora_ffi.find_library/load_library cannot find/open USER32.DLL (Win XP, 11g 11.1.2.1.0)
ora_ffi.find_library/load_library cannot find/open USER32.DLL [message #605360] Wed, 08 January 2014 17:44 Go to next message
aleech1029
Messages: 2
Registered: January 2014
Location: Denver
Junior Member
I am running forms locally on my machine out of developer 11.1.2.1.0 - ora_ffi.find_library('USER32.DLL') and ora_ffi.load_library(NULL,'USER32.DLL) throw an exception 'cannot open library USER32.DLL' - I have checked my PATH variable and c:\Windows\System32 is included - additionally I have modified the code to explicitly reference the directory and still no luck

I believe that I have followed the configuration of webutil to the letter

my apologies up front if this has be previously posted...I have scoured the internet without resolution

Thank you in advance

[Updated on: Wed, 08 January 2014 17:45]

Report message to a moderator

Re: ora_ffi.find_library/load_library cannot find/open USER32.DLL [message #605466 is a reply to message #605360] Thu, 09 January 2014 11:13 Go to previous messageGo to next message
mughals_king
Messages: 351
Registered: January 2012
Location: pakistan
Senior Member
i can provide some stuff i hope this could help you.


here's an ORA_FFI A Worked Example DLL-> Trigger example.


1. The C Code that is the DLL function:
----------------------------------------
#include <string.h>
#include <windows.h>



//Simple C function that just puts something in a string
// and returns the length of that string both as the RC and as a param
// Keeping the C interface as simple as possible.
// The function is exported from the DLL
// You can use the Visual C utility DUMPBIN to check that the
// Function is correctly exported.

__declspec( dllexport ) int PopulateString ( char *FormsBuffer, int *BuffLen)
{
        int LocalLength;
        strcpy(FormsBuffer,"A Fixed string from within the C program");
        *BuffLen    = strlen(FormsBuffer);
        LocalLength = strlen(FormsBuffer);
        return LocalLength;
}


2.  The package Header for the FFI code:
----------------------------------------

PACKAGE FFISample IS
/* So this is the Pubic Interface */
FUNCTION PopulateString ( PopulateString IN OUT VARCHAR2,
                          BuffLen IN OUT PLS_INTEGER)    
                          RETURN PLS_INTEGER;
END FFISample;


3.  The package Body for the FFI code:
--------------------------------------

PACKAGE BODY FFISample IS

 -- Define the various Handles
        lh_ffisamp              ora_ffi.libHandleType;
        fh_PopulateString       ora_ffi.funcHandleType;

 -- Define internal versions of the functions

    /* The interface function, note how the C Pointers map to
       IN OUT variables! */
    FUNCTION i_PopulateString ( funcHandle      IN ora_ffi.funcHandleType,
                                PopulateString  IN OUT VARCHAR2,
                                BuffLen         IN OUT PLS_INTEGER)
                                RETURN PLS_INTEGER;
 -- interface the internal function to the C call interface
    PRAGMA INTERFACE(C,i_PopulateString,11265);

 -- Body of the Externalised function
    FUNCTION PopulateString (   PopulateString  IN OUT VARCHAR2,
                                BuffLen         IN OUT PLS_INTEGER)
                                RETURN PLS_INTEGER IS
    -- declare the buffer padded to the max possible length of the string
    -- This is an In Out var so PopulateString may already have some
    --  content
        /* This RPAD ensures that the VARCHAR string occupies
           contiguous memory */
        PopulateString_l        VARCHAR2(255)  :=  
RPAD(SUBSTR(NVL(PopulateString,' '),1,255),255,CHR(0));

    -- internal buffer for the Int no padding required here.
        BuffLen_l               PLS_INTEGER := BuffLen;
        rc                      PLS_INTEGER;
   BEGIN
     -- Call the internal version of the function with the local buffers
     rc  := i_PopulateString( fh_PopulateString, PopulateString_l, BuffLen_l);

     -- Reset the Real variables with the contents of the buffer
     PopulateString := PopulateString_l;
     BuffLen := BuffLen_l;

   RETURN (rc);
   END ;

-- Package Body Block, handles loading the DLL into memory and registering the
Functions
BEGIN
     BEGIN
        -- Try and fin the DLL already loaded
        lh_ffisamp := ora_ffi.find_library('ffisamp.dll');
     EXCEPTION WHEN ora_ffi.FFI_ERROR THEN
        -- Ok not found lets load it
        -- The null argument for the LOAD library is the DLL location so if
        -- the DLL was not in
        -- the working DIR or not in the PATH soemwhere we might want to
        -- put something in here.
        lh_ffisamp := ora_ffi.load_library(NULL,'ffisamp.dll');
     END ;
     
     -- Now register the PopulateString
     fh_PopulateString :=  ora_ffi.register_function(lh_ffisamp,
                           'PopulateString',ora_ffi.C_STD);
     ora_ffi.register_parameter(fh_PopulateString,ORA_FFI.C_CHAR_PTR);
     ora_ffi.register_parameter(fh_PopulateString,ORA_FFI.C_INT_PTR);
     ora_ffi.register_return(fh_PopulateString,ORA_FFI.C_INT);

EXCEPTION /* Generic FFI Error Handler to unwind the TOOL_ERR stack */
        when others then
                for iCounter in 1..tool_err.nerrors LOOP
                        message(tool_err.message);
                        tool_err.pop;
                end loop;
END FFISample;


4.  Finally a sample forms trigger that calls the C code:
---------------------------------------------------------
   (this might be say on a When-Button-Pressed  trigger)

declare
  StringBuffer varchar2(255)
           := 'An initial value that will be overwritten';
  StringLength pls_integer   := length(StringBuffer);
  RC           pls_integer;
begin
  message('Before Calling My c the value of the string is:'||
           StringBuffer);
  message('Old Length '||to_char(StringLength));
  RC := FFISample.PopulateString(StringBuffer,StringLength);
  message('The New value for String is: '||StringBuffer);
  message('New Length '||to_char(StringLength));
  message('RC was '||to_char(RC));
end;
.

the end.
 

another doc, may be useful:

ORAFFI: PASSING CHARACTER STRING POINTERS BACK FROM ORA_FFI FUNCTIONS
 
Problem Description:
====================
 
You need know the details on passing a character string pointer (char*) back
from a function into ORA_FFI.
 
Symptoms of improper implementations of this may be a GPF in DE15WIN.DLL.
 
 
Related Terms:
==============
ORAFFI
PTR
LPCTSTR
DLL

Solution Description:
=====================
 
The memory for the char pointer must be globally allocated using a GlobalAlloc
(with the GMEM_FIXED flag) such that the memory is not resident on the stack.
The problem with allocating memory on the stack for the pointer is that this
memory block will be freed when the function exits and the returned pointer
will become invalid.
 
Here is a complete example showing a successful implementation of this
functionality. Although the following code demonstrates a 16bit
implementation, the same holds true for 32bit implementations.
 
-- ********************************************************* --
-- This calling trigger's code                                --
-- ********************************************************* --
 
declare
  -- Parameters
  parm1 VARCHAR2(128) := 'X';
  -- Return value
  rt VARCHAR2(512) := 'Hello Folks';
begin
  rt := MyLib.MyFunc1( parm1 );
  Message(rt);
end;
 
-- ********************************************************* --
-- This wrapper package's header                             --
-- ********************************************************* --
 
PACKAGE MyLib IS
  FUNCTION MyFunc1( parm1 IN OUT VARCHAR2 )
                    RETURN VARCHAR2;  
END;
 
 
-- ********************************************************* --
-- This wrapper package's body                               --
-- ********************************************************* --
 
PACKAGE BODY MyLib IS
  lib_hndl  ora_ffi.libHandleType;  
  func_hndl ora_ffi.funcHandleType;  
   
  FUNCTION i_MyFunc1( func_hndl IN ora_ffi.funcHandleType,  
                      parm1 IN OUT VARCHAR2 )
                      RETURN VARCHAR2;  
   
  PRAGMA INTERFACE(C,i_MyFunc1,11265);  
   
  FUNCTION MyFunc1( parm1 IN OUT VARCHAR2 )
                      RETURN VARCHAR2  
  IS    
    parm1_l  VARCHAR2 := parm1;
    rc       VARCHAR2(512);
  BEGIN    
    rc  := i_MyFunc1(func_hndl, parm1_l);
    RETURN (rc);  
  END ;  
   
BEGIN    
  lib_hndl := ora_ffi.load_library(NULL,'DLL16.DLL');  
  func_hndl :=
ora_ffi.register_function(lib_hndl,'PASCAL_TEST',ora_ffi.PASCAL_STD);
  ora_ffi.register_parameter(func_hndl,ORA_FFI.C_CHAR_PTR);
  ora_ffi.register_return(func_hndl,ORA_FFI.C_CHAR_PTR);
END;
 
 
-- ********************************************************* --
-- This DLL's DEF file                                       --
-- ********************************************************* --
 
LIBRARY      DLL16
 
EXETYPE      WINDOWS
 
CODE         PRELOAD MOVEABLE DISCARDABLE
DATA         PRELOAD SINGLE
           
HEAPSIZE     4096
 
EXPORTS
             WEP PRIVATE
             Pascal_Test  @1
 
 
-- ********************************************************* --
-- This DLL's CPP file                                       --
-- ********************************************************* --
 
#include <windows.h>
#include <string.h>
 
int CALLBACK LibMain(HANDLE hInstance, WORD wDataSeg, WORD wHeapSize, LPSTR
lpszCmdLine)
{
        if (wHeapSize > 0 )
                UnlockData (0);  // Unlocks the library's data segment
        return 1;
}
 
char* FAR PASCAL __export Pascal_Test (char* xyz)  
{
    HGLOBAL hgl;
    char FAR* abc;
 
    hgl = GlobalAlloc(GPTR, 256);
    abc = (char*)GlobalLock(hgl);
    strcpy(abc,"Hello World");
        GlobalUnlock(hgl);
 
        MessageBox(NULL,abc,"Pascal",MB_OK);
    return abc;

. the end.
 

more stuff, see ***** below on "scalar" only variables being support by ORA_FFI.

Problem Description:
====================
 
What is ORA_FFI?
Where do you find documentation on ORA_FFI?
What are the differences between ORA_FFI and user exits?

ORA_FFI ENABLES PL/SQL TO CALL 3GL ROUTINES IN EXTERNAL LIBRARIES

Solution Description:
=====================
 
This is an excerpt from the Oracle Procedure Builder Release Notes:
 
Q: What is ORA_FFI?  Does it offer any benefits over user_exits?
     
A: ORA_FFI stands for Oracle Foreign Function Interface.  It is a built-in  
   PL/SQL package that provides services for integrating with third-party  
   Dynamic Link Libraries.
     
   The bindings from PL/SQL program units to foreign functions are
   established DYNAMICALLY at runtime -- NOT compile time -- obviating
   the need to relink executables each time updates are made.  
     
   Because bindings are dynamic, ORA_FFI provides a much more  
   extensible solution than user exits.  If two companies wanted to  
   build forms applications that both had a user exit DLL, it was a  
   real problem because there can only be one forms user exit DLL  
   (F40XTB.DLL).
     
   In addition, there are already many third-party DLLs available,
   including the Windows API library.  ORA_FFI enables developers
   to integrate with these DLLs with little or no additional C
   coding.  User exits may require a substantial amount of C coding
   apart from the work that still must be done in PL/SQL.
 
 
Note:  The ORA_FFI call is only available on the client side PL/SQL
       engine, not the server side.  Typically, it is used from the
       Forms environment.
*******Q: Does ORA_FFI offer support for passing pointers or structures?
     
A: ORA_FFI only offers support for passing scalar values.
   Many people do not consider this a hinderance because it is
   relatively easy to write a small wrapper DLL.  Functions in
   this auxiliary DLL would accept arguments which are used to establish
   the necessary structure(s) that gets passed to the primary
   DLL.
     
   Also, there are already many useful Windows calls which do not
   require structured arguments.  For example, all of the Profile
   functions (GetPrivateProfileString) do not require structured
   arguments.
 
 
Q: Does ORA_FFI work on platforms other than Microsoft Windows?
     
A: ORA_FFI will work on any platform that supports dynamic loading.
   Besides Windows, SunOS, VMS, and Mac are examples of other
   platforms where developers can exploit ORA_FFI.
 
 
Additional Information:
=======================
 
Oracle Documentation:
---------------------
Oracle Procedure Builder 1.5 Developer's Guide Manual
Chapter 8, Oracle Procedure Builder Packages
The ORA_FFI Package
 
Oracle Support Bulletins:  
-------------------------  
9247635.61  
CALLING WINDOWS APPLICATIONS FROM ORACLE FORMS 4.5
 
Oracle Web Sites:
-----------------
You can download examples along with the White Paper "Boosting Development
Productivity with Foreign Function Calls" from the following web sites:  
 
16-bit  
------  
[url]ftp://support.oracle.com/desktop/download/woraffi.exe[/url]  
 
32-bit  
------  
[url]ftp://support.oracle.com/desktop/download/ntoraffi.exe[/url]  
 
If you have difficulties connecting to the server,  
substitute the IP address for the server name (192.86.154.93).
 

Expert Comment

by: ORACLEtunePosted on 2002-06-22 at 16:33:40ID: 7101141
Rank: Master

more stuff, see ***** below on "scalar" only variables being support by ORA_FFI.

Problem Description:
====================
 
What is ORA_FFI?
Where do you find documentation on ORA_FFI?
What are the differences between ORA_FFI and user exits?

ORA_FFI ENABLES PL/SQL TO CALL 3GL ROUTINES IN EXTERNAL LIBRARIES

Solution Description:
=====================
 
This is an excerpt from the Oracle Procedure Builder Release Notes:
 
Q: What is ORA_FFI?  Does it offer any benefits over user_exits?
     
A: ORA_FFI stands for Oracle Foreign Function Interface.  It is a built-in  
   PL/SQL package that provides services for integrating with third-party  
   Dynamic Link Libraries.
     
   The bindings from PL/SQL program units to foreign functions are
   established DYNAMICALLY at runtime -- NOT compile time -- obviating
   the need to relink executables each time updates are made.  
     
   Because bindings are dynamic, ORA_FFI provides a much more  
   extensible solution than user exits.  If two companies wanted to  
   build forms applications that both had a user exit DLL, it was a  
   real problem because there can only be one forms user exit DLL  
   (F40XTB.DLL).
     
   In addition, there are already many third-party DLLs available,
   including the Windows API library.  ORA_FFI enables developers
   to integrate with these DLLs with little or no additional C
   coding.  User exits may require a substantial amount of C coding
   apart from the work that still must be done in PL/SQL.
 
 
Note:  The ORA_FFI call is only available on the client side PL/SQL
       engine, not the server side.  Typically, it is used from the
       Forms environment.
*******Q: Does ORA_FFI offer support for passing pointers or structures?
     
A: ORA_FFI only offers support for passing scalar values.
   Many people do not consider this a hinderance because it is
   relatively easy to write a small wrapper DLL.  Functions in
   this auxiliary DLL would accept arguments which are used to establish
   the necessary structure(s) that gets passed to the primary
   DLL.
     
   Also, there are already many useful Windows calls which do not
   require structured arguments.  For example, all of the Profile
   functions (GetPrivateProfileString) do not require structured
   arguments.
 
 
Q: Does ORA_FFI work on platforms other than Microsoft Windows?
     
A: ORA_FFI will work on any platform that supports dynamic loading.
   Besides Windows, SunOS, VMS, and Mac are examples of other
   platforms where developers can exploit ORA_FFI.
 
 
Additional Information:
=======================
 
Oracle Documentation:
---------------------
Oracle Procedure Builder 1.5 Developer's Guide Manual
Chapter 8, Oracle Procedure Builder Packages
The ORA_FFI Package
 
Oracle Support Bulletins:  
-------------------------  
9247635.61  
CALLING WINDOWS APPLICATIONS FROM ORACLE FORMS 4.5
 
Oracle Web Sites:
-----------------
You can download examples along with the White Paper "Boosting Development
Productivity with Foreign Function Calls" from the following web sites:  
 
16-bit  
------  
[url]ftp://support.oracle.com/desktop/download/woraffi.exe[/url]  
 
32-bit  
------  
[url]ftp://support.oracle.com/desktop/download/ntoraffi.exe[/url]  
 
If you have difficulties connecting to the server,  
substitute the IP address for the server name (192.86.154.93).
 
more stuff, see ***** below on "scalar" only variables being support by ORA_FFI.

Problem Description:
====================
 
What is ORA_FFI?
Where do you find documentation on ORA_FFI?
What are the differences between ORA_FFI and user exits?

ORA_FFI ENABLES PL/SQL TO CALL 3GL ROUTINES IN EXTERNAL LIBRARIES

Solution Description:
=====================
 
This is an excerpt from the Oracle Procedure Builder Release Notes:
 
Q: What is ORA_FFI?  Does it offer any benefits over user_exits?
     
A: ORA_FFI stands for Oracle Foreign Function Interface.  It is a built-in  
   PL/SQL package that provides services for integrating with third-party  
   Dynamic Link Libraries.
     
   The bindings from PL/SQL program units to foreign functions are
   established DYNAMICALLY at runtime -- NOT compile time -- obviating
   the need to relink executables each time updates are made.  
     
   Because bindings are dynamic, ORA_FFI provides a much more  
   extensible solution than user exits.  If two companies wanted to  
   build forms applications that both had a user exit DLL, it was a  
   real problem because there can only be one forms user exit DLL  
   (F40XTB.DLL).
     
   In addition, there are already many third-party DLLs available,
   including the Windows API library.  ORA_FFI enables developers
   to integrate with these DLLs with little or no additional C
   coding.  User exits may require a substantial amount of C coding
   apart from the work that still must be done in PL/SQL.
 
 
Note:  The ORA_FFI call is only available on the client side PL/SQL
       engine, not the server side.  Typically, it is used from the
       Forms environment.
*******Q: Does ORA_FFI offer support for passing pointers or structures?
     
A: ORA_FFI only offers support for passing scalar values.
   Many people do not consider this a hinderance because it is
   relatively easy to write a small wrapper DLL.  Functions in
   this auxiliary DLL would accept arguments which are used to establish
   the necessary structure(s) that gets passed to the primary
   DLL.
     
   Also, there are already many useful Windows calls which do not
   require structured arguments.  For example, all of the Profile
   functions (GetPrivateProfileString) do not require structured
   arguments.
 
 
Q: Does ORA_FFI work on platforms other than Microsoft Windows?
     
A: ORA_FFI will work on any platform that supports dynamic loading.
   Besides Windows, SunOS, VMS, and Mac are examples of other
   platforms where developers can exploit ORA_FFI.
 
 
Additional Information:
=======================
 
Oracle Documentation:
---------------------
Oracle Procedure Builder 1.5 Developer's Guide Manual
Chapter 8, Oracle Procedure Builder Packages
The ORA_FFI Package
 
Oracle Support Bulletins:  
-------------------------  
9247635.61  
CALLING WINDOWS APPLICATIONS FROM ORACLE FORMS 4.5
 
Oracle Web Sites:
-----------------
You can download examples along with the White Paper "Boosting Development
Productivity with Foreign Function Calls" from the following web sites:  
 
16-bit  
------  
[url]ftp://support.oracle.com/desktop/download/woraffi.exe[/url]  
 
32-bit  
------  
[url]ftp://support.oracle.com/desktop/download/ntoraffi.exe[/url]  
 
If you have difficulties connecting to the server,  
substitute the IP address for the server name (192.86.154.93).
 

more stuff, see ***** below on "scalar" only variables being support by ORA_FFI.

Problem Description:
====================
 
What is ORA_FFI?
Where do you find documentation on ORA_FFI?
What are the differences between ORA_FFI and user exits?

ORA_FFI ENABLES PL/SQL TO CALL 3GL ROUTINES IN EXTERNAL LIBRARIES

Solution Description:
=====================
 
This is an excerpt from the Oracle Procedure Builder Release Notes:
 
Q: What is ORA_FFI?  Does it offer any benefits over user_exits?
     
A: ORA_FFI stands for Oracle Foreign Function Interface.  It is a built-in  
   PL/SQL package that provides services for integrating with third-party  
   Dynamic Link Libraries.
     
   The bindings from PL/SQL program units to foreign functions are
   established DYNAMICALLY at runtime -- NOT compile time -- obviating
   the need to relink executables each time updates are made.  
     
   Because bindings are dynamic, ORA_FFI provides a much more  
   extensible solution than user exits.  If two companies wanted to  
   build forms applications that both had a user exit DLL, it was a  
   real problem because there can only be one forms user exit DLL  
   (F40XTB.DLL).
     
   In addition, there are already many third-party DLLs available,
   including the Windows API library.  ORA_FFI enables developers
   to integrate with these DLLs with little or no additional C
   coding.  User exits may require a substantial amount of C coding
   apart from the work that still must be done in PL/SQL.
 
 
Note:  The ORA_FFI call is only available on the client side PL/SQL
       engine, not the server side.  Typically, it is used from the
       Forms environment.
*******Q: Does ORA_FFI offer support for passing pointers or structures?
     
A: ORA_FFI only offers support for passing scalar values.
   Many people do not consider this a hinderance because it is
   relatively easy to write a small wrapper DLL.  Functions in
   this auxiliary DLL would accept arguments which are used to establish
   the necessary structure(s) that gets passed to the primary
   DLL.
     
   Also, there are already many useful Windows calls which do not
   require structured arguments.  For example, all of the Profile
   functions (GetPrivateProfileString) do not require structured
   arguments.
 
 
Q: Does ORA_FFI work on platforms other than Microsoft Windows?
     
A: ORA_FFI will work on any platform that supports dynamic loading.
   Besides Windows, SunOS, VMS, and Mac are examples of other
   platforms where developers can exploit ORA_FFI.
 
 
Additional Information:
=======================
 
Oracle Documentation:
---------------------
Oracle Procedure Builder 1.5 Developer's Guide Manual
Chapter 8, Oracle Procedure Builder Packages
The ORA_FFI Package
 
Oracle Support Bulletins:  
-------------------------  
9247635.61  
CALLING WINDOWS APPLICATIONS FROM ORACLE FORMS 4.5
 
Oracle Web Sites:
-----------------
You can download examples along with the White Paper "Boosting Development
Productivity with Foreign Function Calls" from the following web sites:  
 
16-bit  
------  
[url]ftp://support.oracle.com/desktop/download/woraffi.exe[/url]  
 
32-bit  
------  
[url]ftp://support.oracle.com/desktop/download/ntoraffi.exe[/url]  
 
If you have difficulties connecting to the server,  
substitute the IP address for the server name (192.86.154.93).


Regard
Mughal

[Updated on: Thu, 09 January 2014 11:14]

Report message to a moderator

Re: ora_ffi.find_library/load_library cannot find/open USER32.DLL [message #605467 is a reply to message #605466] Thu, 09 January 2014 11:18 Go to previous message
aleech1029
Messages: 2
Registered: January 2014
Location: Denver
Junior Member
I should have been more specific in my original post - this code is legacy code and exists in a common library that is integral to our enterprise application. It's been around since at least 1998 and has worked without issue. I recently upgraded to Forms 11.1.2.1.0 and this code now throws an exception when running forms locally on my machine (Win XP) directly out of developer.

Still looking for suggestions/ideas...
Previous Topic: I want to show movable image on form like data loding symbol
Next Topic: Getting ORA-12154: TNS error when running a form
Goto Forum:
  


Current Time: Sat Aug 23 13:10:23 CDT 2014

Total time taken to generate the page: 0.12000 seconds