Re: [Q] Compatibility of Oracle Pro*C and C++
Date: Fri, 1 Oct 1993 18:33:03 GMT
Message-ID: <Jim_Holt-011093132344_at_jolt.sps.mot.com>
In article <MLOENNRO.93Oct1010026_at_wrpyr4.us.oracle.com>, mloennro_at_us.oracle.com (Magnus Lonnroth) wrote:
> In article <1993Sep30.191612.6775_at_nynexst.com> dmj_at_seneca.nynexst.com (David Johnson) writes:
>
> [stuff deleted]
>
> At the moment, there is no way of including embedded SQL in C++ modules.
> To use Pro*C v1 (and v2 soon to be released) you must write extern C
> modules that isolate db-access. A major drawback is also that cursors
> must be hard-coded and are precompiled into globals, making it difficult
> to write "generic" functions.
>
This is not strictly true. I have achieved both SQL embedded in C++, and I have a "generic" cursor method which encapsulates the 4th method of dynamic SQL inside a C++ base class. The only real difficulty is getting the function prototypes generated by the Pro*C compiler cleaned up so that the C++ compile can occur. I have a short awk script which can be run to solve this problem. The idea is to precompile your C++ code, run it through the awk script, and then compile. I include awk script below. It was orinially given to me by Jan Paatero and worked for Oracle v6.XX. I have modified it to work under Oracle7.
Hope this helps...
-jh
- name your C++ source file with embedded SQL "filename.C.pc"
- alter your Makefile to include the lines below
- copy the awk script below into a file named "pc_to_C"
Makefile stuff follows
-----------------------START filename.C: filename.C.pc filename.h $(PROC) $(PROCFLAGS) iname=filename.C.pc host=c echo Fixing... _at_pc_to_C filename.c _at_mv filename.c filename.C -----------------------END
Awk script follows
-----------------------START #!/bin/sh #------------------------------------------------------------------ # This is a script that was sent to me from a lady in Australia. # I had posted on the net asking how to mix Pro*C and C++ in the # same source file. I leave the comments intact below ... # # Jim Holt 3/15/1993 # # Modified : 8/11/1993 to correct problems with Oracle7 #------------------------------------------------------------------ # # Hello Netland and especially David Hudek, # # In article <145384_at_lll-winken.LLNL.GOV> David Hudek had questions # about Oracle's Pro*C precompiler and C++. # #> Is there any reason why the output of Pro*C couldn't then be #> run through Sun's C++ compiler and produce good executables? (since the #> C++ compiler can obviously handle straight C code). # # The most important experience of mine is: Yes, they can be integrated # and the executables work. (At least in my case --- I've been using # Oracle version 6, Pro*C precompiler version 1.3 and C++ version 2.1 # in HP risc boxes, Tandem S2 systems and MIPS risc machines.)#
#> The only potential problem I can think of at the moment from a programming
#> standpoint is how function declarations are handled... # # This is true. The workaround that has to be done is to modify the # prototypes of Oracle system calls. As very well known, Pro*C output # has function declarations like # # extern void sqlxxx(); # # The trick that changes these to be compliant with C++ is to change the # declaration to varparam (three dots inside parenthesis) and typesafe C # linkage. So the previous declaration should be modified to something # like # # #ifdef __cplusplus # extern "C" { # #endif /* __cplusplus */ # # extern void sqlxxx(...); # # #ifdef __cplusplus # } # #endif /* __cplusplus */ # # The #ifdefs in the previous example are there to make the modified # code also compliant with ANSI standard C. # # Luckily this workaround task can be easily automated. I'm using the # following shell && nawk script which I hereby release to public, # free of charge, with absolutely no warranty of any kind, under GNU # general public licence. # # The script takes the precompiled file as argument, locates the Oracle # system call prototypes and makes the modifications described above to # them. The original file is saved with a suffix .old. # # Hope this helps, # # janne # #/****************************************************************************** # Janne Paatero * "Maybe a db wheenie in Nokia TelecommunicationsOy"
# paatero_at_tele.nokia.fi * "but still speaking only for myself." # paatero_at_ntc.nokia.com * #******************************************************************************/ # #---clipeti--clap---clipeti--clap---clipeti--clap---clipeti--clap---clipeti-- #!/bin/sh # # A simple shell and nawk script to repair output of Pro*C precompiler of # Oracle Inc. to make it compliant with C++. # # Copyright (C) Janne Paatero, 1992. # You may use and redistribute this under GNU general public licence. #
if [ $# -ne 1 ]
then
echo "You should give the name of the file to be repaired." exit 1
fi
awk 'BEGIN {
# Set up global variables, types and parameters.
first = 1 last = 0
}
function beginToken() {
printf("/*******************************************************/\n") printf("/*** Repaired for C++ by PCCrepair ***/\n") printf("/*** PCCrepair script by J.Paatero ***/\n") printf("/*** Updated for Oracle7 by J. Holt ***/\n") printf("/*******************************************************/\n") printf("#ifdef __cplusplus\n") printf("extern \"C\" {\n") printf("#endif /* __cplusplus */\n")
}
function endToken() {
printf("#ifdef __cplusplus\n") printf("}\n") printf("#endif /* __cplusplus */\n") }
function fixSQLDA() {
printf("/*******************************************************/\n") printf("/*** Repaired for C++ by PCCrepair ***/\n") printf("/*** PCCrepair script by J.Paatero ***/\n") printf("/*** Updated for Oracle7 by J. Holt ***/\n") printf("/*******************************************************/\n") printf("#ifdef __cplusplus\n") printf("extern \"C\" {\n") printf("#endif /* __cplusplus */\n") printf("extern SQLDA *sqlald(...);\n"); printf("extern void sqlnul(...);\n"); printf("extern void sqlprc(...);\n"); printf("extern void sqlclu(...);\n"); printf("#ifdef __cplusplus\n") printf("}\n") printf("#endif /* __cplusplus */\n")
}
{
while ($1 == "extern" && $2 == "void" && $3 ~ /^sql/ && $3 ~ /\(\);$/){ if (first) { first = 0 last = 1 beginToken() } sub(/\(\);$/, "(...);") print getline } first = 1 while ($1 == "extern" && $2 != "\"C\"" && $2 != "struct"){ if (first) { first = 0 last = 1 beginToken() } sub(/\/.*\//,"...") if ($2 != "SQLDA" && $2 != "void") sub("extern","extern void"); sub(/\(\);$/, "(...);") print getline } if (last) { last = 0 endToken() } if ($1 == "typedef" && $2 == "struct" && $3 == "SQLDA") { print fixSQLDA() }
else print
}
END { }' $1 >/tmp/PCCrepair.$$
mv -f $1 $1.old
cp /tmp/PCCrepair.$$ $1
rm /tmp/PCCrepair.$$
exit 0
-------------------------END +--------------------------------------------------------------------+ | I used to have a catchy signature, but I forgot what it was ... | | | | Jim Holt | | Motorola, Inc Jim_Holt_at_aprdlgtr.sps.mot.com | +--------------------------------------------------------------------+Received on Fri Oct 01 1993 - 19:33:03 CET