Oracle Pro*C with Visual Studio 2015
By: Date: August 14, 2018 Categories: Enterprise Computing,Oracle Tags:

I recently had need to upgrade a small C program from a much older version of Microsoft Visual Studio to Visual Studio 2015.

After updating the pcscfg.cfg file and makefile to point to the latest directories, I immediately ran into problems with numerous errors with the Pro*C pre-compiler when it was processing Microsoft include files.  Many of these errors were in reference to various typedef statements, the first of which seemed to be in vcruntime.h.

Since I was initially using the Oracle 11.2 client, I upgraded to the Oracle 12.2 client to see if this had any positive impact, but it didn’t.  The pre-compiler was still choking on the same header file code. 

Re-reading the Pro*C documentation, I found that it was stated that on the Windows platform the setting for parse was set to none by default, whereas on other platforms it defaults to full.  A reason isn’t given for this default, but I suspect it just comes down to the Pro*C pre-compiler not being able to follow the various typedef and other statements in the latest Visual Studio header files.

When parse is set to full, Pro*C reads all of the various header files, includes, etc as it parses the code.  It also provides one distinct advantage:  You do not need to surround variable declarations with SQL DECLARE statements.  When parse is set to partial or none, you must surround bind variables that you plan to use in SQL statements with declaration blocks.  For example:

EXEC SQL BEGIN DECLARE SECTION;
 int l_user;
 char l_array[128];
EXEC SQL END DECLARE SECTION;

EXEC SQL 
  SELECT my_user
    INTO :l_user
    FROM my_table;

In my case, since I had originally written the code with parse=full, I had to go back through the source and surround variable declarations as above once I changed to parse=partial.  Because the program was small, this wasn’t a great hardship once I determined what needed to be done.

When you compile, the Pro*C pre-compiler will throw errors referencing unknown identifiers in your SQL statements for any variables that it doesn’t find within DECLARE sections.

In most cases, I simply had to add the SECTION header and footer statements.  However, in one case, where I was referencing function parameters within a SQL statement, I had to make local copies of those variables as I could not find a way for the pre-compiler to recognize the variables as declared within the function specification.  For example:

//Doesn't work with parse=none
function void MyUpdate( char *S ) {

EXEC SQL
  INSERT
    INTO my_table
         (my_column)
  VALUES (:S);
}

Had to become this:

function void MyUpdate( char *S ) {

EXEC SQL BEGIN DECLARE SECTION;
 char *L = S;
EXEC SQL END DECLARE SECTION;

EXEC SQL
  INSERT
    INTO my_table
         (my_column)
  VALUES (:L);
}

I suspect in a very large program, this could become a chore.  My source has its Pro*C pieces isolated in just a few source files.