Chapter Contents

Previous

Next
Using the indep Option for Interlanguage Communication

Using Interlanguage Communication

This section explains how to create programs that use interlanguage calls in more than one direction as well as how to share data between languages.


Calls to C

C code compiled with indep can be called from FORTRAN, COBOL, PL/I, or any other language that uses standard IBM 370 linkage conventions, provided that the differences between C parameter passing conventions and those of other languages are understood. Briefly, most languages use call by reference, while C uses call by value. For example, if a FORTRAN routine calls a C program, passing an INTEGER value, the corresponding C parameter must be declared to have type int * (pointer to int ), not int .


Calls from C

In the simple case where C is called from another high-level language and no interlanguage calls are made by C, the use of indep is often the only special requirement. Sometimes, however, there is a need to support calls in both directions. If direct calls from C to the other language cause no problems, you do not need to read the rest of this section.

For many languages, direct calls from C to subroutines in the other language fail to work because the called language requires access to its own execution framework. For example, PL/I code requires that register 12 address the PL/I TCA rather than the CRAB. For such languages, before calling the subroutine, you must arrange for the creation of an execution framework for the other high-level language. When the subroutine is invoked, you must arrange for the other language's framework to be in effect. When you are finished with subroutines in the other language, you must arrange to terminate the other language framework. You may need to write assembler stubs to perform some or all of these functions.

The exact details depend on the implementation of the other language and its execution framework and on any restrictions it imposes. You should read the section or sections on interlanguage communication in the appropriate manual for the other language. C is like assembler for many purposes, so you should also study the discussion on communication with assembler. The steps required are outlined here.

First, create an execution framework for the other language. The best way to do this is to call a MAIN routine written in the other language, unless the language provides a specific call to accomplish this function. The other language's framework can be created before or after the C framework. If you create it after the C framework, calling a C function compiled with indep returns to the C execution framework if provision has been made for this as described under main Function Considerations.

C functions compiled with indep can be called from the other language exactly as described under Calls to C.

You cannot call other language subroutines directly from C functions, unless the other language implementation has a facility similar to indep . Instead, you must call an assembler routine to switch execution frameworks. After saving the registers from C, the stub must reactivate the framework for the other language and call the appropriate subroutine. To assist you with this, a sample macro named L$UPENV is provided. This macro is in some ways the inverse of the L$UCENV macro: it determines whether the C framework is active and, if so, switches to the framework from which C was called. L$UPENV has a single argument, REG=, that specifies the register that is to contain the framework pointer. This register is restored from the save area of the routine that called the first active C routine. If this procedure is not adequate for the particular language in use, you can modify L$UPENV as necessary.

Your assembler routine should invoke the L$UPENV macro (modified as necessary) and then invoke the other language routine. Sample PLISUB Routine may be helpful. You may want to write one stub per subroutine or have one stub handle multiple subroutines, as in Sample L$URTOP Routine.

You may need to pass on parameters from the C caller to the other language subroutine. The @ operator and the __ref function modifier (language extensions) can be helpful in passing parameters to another language. These extensions are described in Source Code Conventions.

The other language subroutines can call other subroutines in the other language, C functions compiled with indep , and assembler subroutines.

When you are through calling all other language subroutines, you need to terminate the execution framework of the other language. You should terminate the frameworks in the opposite order in which they were created. (That is, the framework created last should be terminated first.) If you terminate C first, simply call L$UEXIT from the other language as described above. To terminate the other language's framework first, return from the other language's MAIN routine. When you do this, control is returned to the point in C from which you originally invoked the MAIN routine in the other language.


Data Sharing

In general, data belonging to another language that are to be referenced from C must be accessed via pointers. FORTRAN and PL/I provide exceptions to this. If your C program is compiled with the norent compiler option, it can access FORTRAN COMMONs (except for dynamic COMMONs) and PL/I STATIC EXTERNAL variables as extern data. For details, see Sharing External Variables with FORTRAN Programs.


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.