HPlogo HP C/HP-UX Programmer's Guide: Workstations and Servers > Chapter 5 Programming for Portability

Calling Other Languages

» 

Technical documentation

Complete book in PDF

 » Table of Contents

 » Index

It is possible to call a routine written in another language from a C program, but you should have a good reason for doing so. Using more than one language in a program that you plan to port to another system will complicate the process. In any case, make sure that the program is thoroughly tested in any new environment.

If you do call another language from C, you will have the other language's anomalies to consider plus possible differences in parameter passing. Since all HP-UX system routines are C programs, calling programs written in other languages should be an uncommon event. If you choose to do so, remember that C passes all parameters by value except arrays and structures. The ramifications of this depend on the language of the called function.

Table 5-5 C Interfacing Compatibility

C

HP-UX Pascal

FORTRAN

char

none

byte

unsigned char

char

character (could reside on an odd boundary and cause a memory fault)

char * (string)

none

none

unsigned char * (string)

PAC+chr(0) (PAC = packed array[1..n] of char)

Array of char+char(0)

short (int)

-32768..32767 (shortint on Series 700/800)

integer*2

unsigned short (int)

BIT16 on Series 700/800; none on Series 300/400 (0..65535 will generate a 16-bit value only if in a packed structure)

none

int

integer

integer (*4)

long (int)

integer

integer (*4)

unsigned (int)

none

none

float

real

real (*4)

double

longreal

real*8

long double [1]

none

real*16

type* (pointer)

^var, pass by reference, or use anyvar

none

&var (address)

addr(var) (requires $SYSPROG$)

none

*var (deref)

var^

none

struct

record (cannot always be done; C and Pascal use different packing algorithms)

structure

union

record case of

union

[1] long double is available only in ANSI mode.

 

Calling FORTRAN

You can compile FORTRAN functions separately by putting the functions you want into a file and compiling it with the -c option to produce a .o file. Then, include the name of this .o file on the cc command line that compiles your C program. The C program can refer to the FORTRAN functions by the names they are declared by in the FORTRAN source.

Remember that in FORTRAN, parameters are usually passed by reference (except CHARACTER parameters on Series 700/800, which are passed by descriptor), so actual parameters in a call from C must be pointers or variable names preceded by the address-of operator (&).

The following program uses a FORTRAN block data subprogram to initialize a common area and a FORTRAN function to access that area:

      double precision function get_element(i,j)
double precision array
common /a/array(1000,10)
get_element = array(i,j)
end

block data one
double precision array
common /a/array(1000,10)
C Note how easily large array initialization is done.
data array /1000*1.0,1000*2.0,1000*3.0,1000*4.0,1000*5.0,
* 1000*6.0,1000*7.0,1000*8.0,1000*9.0,1000*10.0/
end

The FORTRAN function and block data subprogram contained in file xx.f are compiled using f77 -c xx.f.

The C main program is contained in file x.c:

main()
{
int i;

extern double get_element(int *, int *);

for (i=1; i <= 10; i++)
printf("element = %f\n", get_element(&i,&i));
}

The C main program is compiled using cc -Aa x.c xx.o.

Another area for potential problems is passing arrays to FORTRAN subprograms. An important difference between FORTRAN and C is that FORTRAN stores arrays in column-major order whereas C stores them in row-major order (like Pascal).

For example, the following shows sample C code:

int i,j;
int array[10][20];

for (i=0; i<10; i++) {
for (j=0; j<20; j++) /* Here the 2nd dimension
varies most rapidly */
array [i][j]=0;
}

Here is similar code for FORTRAN:

integer array (10,20)

do J=1,20
do I=1,10 !Here the first dimension varies most rapidly
array(I,J)=0
end do
end do

Therefore, when passing arrays from FORTRAN to C, a C procedure should vary the first array index the fastest. This is shown in the following example in which a FORTRAN program calls a C procedure:

integer array (10,20)

do j=1,20
do i=1,10
array(i,j)=0
end do
end do
call cproc (array)
.
.
.
cproc (array)
int array [][];

for (j=1; j<20; j++) {
for (i=1; i<20; i++) /* Note that this is the reverse from
how you would normally access the
array in C as shown above */
array [i][j]= ...
}
.
.
.

There are other considerations as well when passing arrays to FORTRAN subprograms.

It should be noted that a FORTRAN main should not be linked with cc.

Calling Pascal

Pascal gives you the choice of passing parameters by value or by reference (var parameters). C passes all parameters (other than arrays and structures) by value, but allows passing pointers to simulate pass by reference. If the Pascal function does not use var parameters, then you may pass values just as you would to a C function. Actual parameters in the call from the C program corresponding to formal var parameters in the definition of the Pascal function should be pointers.

Arrays correlate fairly well between C and Pascal because elements of a multidimensional array are stored in row-major order in both languages. That is, elements are stored by rows; the rightmost subscript varies fastest as elements are accessed in storage order.

Note that C has no special type for boolean or logical expressions. Instead, any integer can be used with a zero value representing false, and non-zero representing true. Also, C performs all integer math in full precision (32-bit); the result is then truncated to the appropriate destination size.

To call Pascal procedures from C on the HP 9000 workstations and servers, a program may first have to call the Pascal procedure U_INIT_TRAPS. See the HP Pascal Programmer's Guide for details about the TRY/RECOVER mechanism.

As true of FORTRAN mains, a Pascal main should not be linked with cc.

The following source is the Pascal module:

   module a;
export
function cfunc : integer;
function dfunc : integer;

implement
function cfunc : integer;
var x : integer;

begin
x := MAXINT;
cfunc := x;
end;

function dfunc : integer;
var x : integer;

begin
x := MININT;
dfunc := x;
end;
end.

The command line for producing the Pascal relocatable object is

$ pc -c pfunc.p

The command line for compiling the C main program and linking the Pascal module is

$ cc x.c pfunc.o -lcl

The following output results:

2147483647
-2147483648
© Hewlett-Packard Development Company, L.P.