Unable to link pre-compiled file

641 Views Asked by At

I am using OpenVMS V8.4 as an Oracle 10g database server with CXX built in compiler as well as PROC compiler provided by oracle.

I have written this sample C program:

sample.c

#include<stdio.h>
exec sql include sqlca;  // adds Oracle PLSQL library
                         // same as #include<sqlca.h>

main() {
    printf("Hello, World!\n");
}

then I compiled it

DEVSERVER> PROC SAMPLE.C SAMPLE.PC

The command works find and I can then use the built in CXX compiler:

DEVSERVER> CXX SAMPLE.PC

The command works without any error and I can now use the built in LINK command:

DEVSERVER> LINK SAMPLE

now I can run the file by:

DEVSERVER> RUN SAMPLE

and I get the expected output:

Hello, World!

So, that's all fine. But my program does not do anything useful yet. So, lets connect to a database schema first. I modified SAMPLE.C to :

#include<stdio.h>
exec sql include sqlca; 

main() {
    printf("Hello, World!\n");

    exec sql connect scott identified by tiger;
    // I skipped checking for sqlca.error since LINKer wont even allow
    //  me to create EXE of this file
}

Now, I pre-compile as before:

DEVSERVER> PROC SAMPLE.C SAMPLE2.PC
DEVSERVER> CXX SAMPLE2.PC
DEVSERVER> LINK SAMPLE2

and here is where I get this error:

%ILINK-W-NUDFSYMS, 1 undefined symbol:
%ILINK-I-UDFSYM,  CX3$Z6SQLCXTPPVPJP6SQLXD384K7FP
%ILINK-W-USEUNDEF, undefined symbol CX3$Z6SQLCXTPPVPJP6SQLXD384K7FP refernced
        source code name: "sqlcxt(void **, unsigned int *, sqlexd *, const sqlcxp *)"
        section: .text
        offset: %X0000000000000350 slot: 2
        module: SAMPLE2
        file: DEV$SERVER[SOURCE]SAMPLE2.OBJ;1

The same error occurs whenever I try to execute any SQL statement within a block of exec sql in the code.

What am I doing wrong?

3

There are 3 best solutions below

1
user3344003 On BEST ANSWER

You are running into a chain reaction of problems: Compilation (c++ name mangling) and linking:

https://docs.oracle.com/cd/E11882_01/server.112/e56697/ch6.htm#VMSAR516

Note the CODE=CPP parameter. That omission is likely your first major headache. It looks like you are the victim of C++ name mangling. It is likely your compiler is translating

 sqlcxt(void **, unsigned int *, sqlexd *, const sqlcxp *)

into

 CX3$Z6SQLCXTPPVPJP6SQLXD384K7FP

Then note the command procedures in the documentation for linking to the Oracle libraries.

0
Bob Jarvis - Слава Україні On

@user3344003's response brings back memories. :-) Yes, he's correct - the name of the procedure created to process the EXEC SQL is being name-mangled, but as it's generated (in assembler, IIRC) by the SQL pre-processor you have to work around this a bit.

The way we used to handle this, back in the day, was to have a separate .c file with a bunch of procedures, each of which performed either a single SQL statement or a logical group of SQL statements needed to perform a task. We also had a .h file with prototypes which matched the routines in the .c file. The header would be #included into the .cpp file, with the function prototypes in the header given an appropriate extern "C" to specify C calling conventions and no name mangling.

Another possibility, which I never tried but which might work, would be to simply put a prototype for sqlcxt(void **, unsigned int *, sqlexd *, const sqlcxp *) into your code, prefaced with extern "C". Might be worth a try, but I can only vouch for the .c file method.

Best of luck.

0
qustogusto On

Just use the C compiler on your OpenVMS server, most likely it's installed too. Oracle's ProC is C too, so you won't be dealing with a lot of CXX quirks. Unless, there're other not mentioned factors that require you to use C++...

As for CXX, depending on which version you use, there used to be a requirement to use CXXLINK instead of LINK command for linking C++ code. Obviously, when mixing C and C++ code, you need to take care of extern "C" for C functions defined in your code.