Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Usenet -> c.d.o.server -> Re: ORA-06522: undefined symbols error

Re: ORA-06522: undefined symbols error

From: Mladen Gogala <gogala_at_sbcglobal.net>
Date: Sun, 31 Oct 2004 17:56:11 -0500
Message-ID: <pan.2004.10.31.22.56.10.721764@sbcglobal.net>


On Fri, 29 Oct 2004 16:27:03 -0700, belanna wrote:

> I have a c++ program that is called from a c program. There is an
> oracle library calling the c program. The c++ library uses extern "C"
> so it can be called from the c program. It runs fine from an
> executable on the command line, but oracle cannot resolve t he c++
> symbols. I know this is a problem with making the c++ library, but
> don't know what it is.

The problem is that you have badly mixed up concepts. C++ allows nasty practices called "method overloading" and "polymorphism". Method overloading allows you to have several different functions with the same name, as long as they have different signatures (see the Gospel of Stroustrup). Polymorphisms makes it possible to invoke the right function when somebody uses something like this: (myobj *)p->my_method(); Again, see the Gospel of Stroustrup. To be able to that, C++ compilers do something called "name mangling". The "extern C" declaration doesn't make C++ callable from outside, it tells the compiler that "signature" will not be included in the symbol name for that routine. Here is part of the "nm" listing from a library that used in a C++ program which works with oracle:

        U __cxa_allocate_exception
         U __cxa_throw
         U __gxx_personality_v0
         U _IO_putc
         U OCIAttrGet
         U OCIBindByName
         U OCIBindByPos
         U OCIDefineByPos
         U OCIHandleAlloc
         U OCIHandleFree
         U OCIParamGet
         U OCIStmtExecute
         U OCIStmtFetch
         U OCIStmtPrepare
         U printf
         U stdout
         U strncpy
         U _Z12createColumnP16ColumnDescriptori
00000be0 T _Z12DisplayTitleP9OciCursor
         U _ZdlPv
         U _ZN10OciContext10CheckErrorEi
         U _ZN10OciContext8GetErrorEv
00000000 W _ZN13lib_exceptionC1Ei
         U _ZN8OciErrorC1EP10OciContext
00000b70 T _ZN9OciCursor10DisplayRowEic
000009e4 T _ZN9OciCursor12FunctionTypeEv
00000a28 T _ZN9OciCursor13MakeResultSetEi
0000098c T _ZN9OciCursor14GetColumnCountEv
0000078c T _ZN9OciCursor14OciDescribePosEi
0000047c T _ZN9OciCursor4BindEP6columni
0000058c T _ZN9OciCursor4BindEP6columnPc
000004d4 T _ZN9OciCursor4BindEPS_i
000005fc T _ZN9OciCursor4BindEPS_Pc
00000354 T _ZN9OciCursor4ExecEi
00000424 T _ZN9OciCursor5BindnEP6columniPi
0000051c T _ZN9OciCursor5BindnEP6columnPcPi
000006b0 T _ZN9OciCursor5FetchEi
000001c0 T _ZN9OciCursor5ParseEPKc
0000065c T _ZN9OciCursor6DefineEP6columni
000003e0 T _ZN9OciCursor8RowCountEv
000000e0 T _ZN9OciCursorC1EPKcP10OciContextP6OciEnv

If you take a look at the following part

         U OCIStmtExecute
         U OCIStmtFetch
         U OCIStmtPrepare
         U printf


You will notice that the "extern C" symbols like "printf" have easily recognizable names, without any funny characters, while symbols defined in the library have names like:

000001c0 T _ZN9OciCursor5ParseEPKc
0000065c T _ZN9OciCursor6DefineEP6columni
000003e0 T _ZN9OciCursor8RowCountEv
000000e0 T _ZN9OciCursorC1EPKcP10OciContextP6OciEnv

where the name includes the class name, the function name and signature.

Now, when you decide to map a C routine to a PL/SQL procedure, oracle will load the specified library into the listener process using "dlopen" library function and will map your function using a call to "dlsym" (if I am not mistaken, google or man pages should be able to help you with those). To be able to do that, you have to describe the exact location and the name of the library (aka "CREATE LIBRARY") and give it the EXACT NAME of the linker symbol that you want to use from that library. C++ compiler produces horribly mutilated names, not the exact ones. Even worse, each C++ compiler has its own Torquemada-inspired method of mangling names, which means that Oracle cannot possibly know which routine you would like to use. I believe that in Oracle v18, they'll come up with the RPM (Read Programmers Mind) feature, so that oracle will be able to use even badly written C++ routines as external procedures. I'm sure that this will be incorporated in the Omlet software much before that. May the farce be with you.

-- 
Artificial Intelligence is no match for natural stupidity.
Received on Sun Oct 31 2004 - 16:56:11 CST

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US