Re: [Q] Compatibility of Oracle Pro*C and C++

From: Jim Holt <Jim_Holt_at_aprdlgtr.sps.mot.com>
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

  1. name your C++ source file with embedded SQL "filename.C.pc"
  2. alter your Makefile to include the lines below
  3. 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 Telecommunications
Oy"
# 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

Original text of this message