11.4 C Calls to High-Level Languages

Just as you can call Microsoft C routines from other Microsoft languages, you can call routines written in Microsoft FORTRAN and Pascal from C. With FORTRAN, Pascal, and C, freestanding routines can be written with no restriction. When calling BASIC routines, however, you must write the main program in BASIC; any subprograms are free to call one another, whether they are written in C or BASIC.

For information about how to pass particular kinds of data, see “Handling Data in Mixed-Language Programming”.

Executing a Mixed-Language Call

The C interface to other languages uses standard C prototypes, with the __fortran or __pascal keyword. Using either of these keywords causes the routine to be called with the FORTRAN/Pascal naming and calling convention. (The FORTRAN/Pascal convention also works for BASIC.) Here are the recommended steps for executing a mixed-language call from C:

1.Write a prototype for each mixed-language routine called. The prototype should declare the routine extern for the purpose of program documentation.

Instead of using the __fortran or __pascal keyword, you can simply compile with the Pascal calling convention option (/Gc). The /Gc option causes all functions in the module to use the FORTRAN/Pascal naming and calling conventions, except where you apply the __cdecl keyword.

2.Pass the values of variables or pointers to variables. You can obtain a pointer to a variable with the address-of (&) operator.

In C, array names are always passed as pointers to the first element of the array; they are always passed by reference.

The prototype you declare for your function ensures that you are passing the correct length address (that is, near or far).

3.Issue a function call in your program as though you were calling a C function.

4.Always compile the C module in either medium, large, or huge model, or use the __far keyword in your function prototype. This ensures that a far (intersegment) call is made to the routine.

Using the __fortran or __pascal Keyword

There are two rules of syntax that apply when you use the __fortran or __pascal keyword:

The __fortran and __pascal keywords modify only the item immediately to their right.

The __near and __far keywords can be used with the __fortran and __pascal keywords in prototypes. The sequences __fortran __far and __far __fortran are equivalent.

The keywords __pascal and __fortran have the same effect on the program; using one or the other makes no difference except for internal program documentation. Use __fortran to declare a FORTRAN routine, __pascal to declare a Pascal routine, and either keyword to declare a BASIC routine.

The example below declares func to be a BASIC, Pascal, or FORTRAN function taking two short parameters and returning a short value.

short __pascal func( short sarg1, short sarg2 );

The example below declares func to be pointer to a BASIC, Pascal, or FORTRAN routine that takes a long parameter and returns no value. The keyword void is appropriate when the called routine is a BASIC subprogram, Pascal procedure, or FORTRAN subroutine, since it indicates that the function returns no value.

void ( __fortran * func )( long larg );

The example below declares func to be a __near BASIC, Pascal, or FORTRAN routine. The routine receives a double parameter by reference (because it expects a pointer to a double) and returns a short value.

short __near __pascal func( __near double * darg );

The example below is equivalent to the preceding example (__pascal __near is equivalent to __near __pascal).

short __pascal __near func( __near double * darg );

Summary: You can make C adopt the conventions of other languages.

When you call a BASIC subprogram, you must use the FORTRAN/Pascal conventions to make the call. When you call FORTRAN or Pascal, however, you have a choice. You can make C adopt the conventions described in the previous section, or you can make the FORTRAN or Pascal routine adopt the C conventions.

To make a FORTRAN or Pascal routine adopt the C conventions, put the C attribute in the heading of the routine's definition. The following example shows the syntax for the C attribute in a FORTRAN subroutine-definition heading:

SUBROUTINE FFROMC [C] (N)

INTEGER*2 N

The following example shows the syntax for the C attribute in a Pascal procedure-definition heading:

PROCEDURE Pfromc( n : INTEGER ) [C];

To make a C function adopt the FORTRAN/Pascal conventions, declare the function as __fortran or __pascal. For example,

void __pascal CfromP( int n );