📄 pgcmixf.gml
字号:
.chap *refid=cmixf Inter-Language calls: C and FORTRAN
.*
.np
.ix 'inter-language calls'
.ix 'mixed-language programming'
The purpose of this chapter is to anticipate common questions about
mixed-language development using &watc and &watf..
.np
The following topics are discussed in this chapter:
.begbull
.bull
Symbol Naming Convention
.bull
Argument Passing Convention
.bull
Memory Model Compatibility
.bull
Integer Type Compatibility
.bull
How do I pass integers from C to a FORTRAN function?
.bull
How do I pass integers from FORTRAN to a C function?
.bull
How do I pass a string from a C function to FORTRAN?
.bull
How do I pass a string from FORTRAN to a C function?
.bull
How do I access a FORTRAN common block from within C?
.bull
How do I call a C function that accepts a variable number of arguments?
.endbull
.*
.section Symbol Naming Convention
.*
.np
.ix 'mixed-language programming' 'symbol names'
The symbol naming convention describes how a symbol in source form is
mapped to its object form.
Because of this mapping, the name generated in the object file may
differ from its original source form.
.np
Default symbol naming conventions vary between compilers.
&watc prefixes an underscore character to the beginning of variable
names and appends an underscore to the end of function names during
the compilation process.
&watf converts symbols to upper case.
Auxiliary pragmas can be used to resolve this inconsistency.
.np
Pragmas are compiler directives which can provide several
capabilities, one of which is to provide information used for code
generation.
When calling a FORTRAN subprogram from C, we want to instruct the
compiler NOT to append the underscore at the end of the function name
and to convert the name to upper case.
This is achieved by using the following C auxiliary pragma:
.millust begin
#pragma aux ftnname "^";
.millust end
.np
The "^" character tells the compiler to convert the symbol name
"ftnname" to upper case; no underscore character will be appended.
This solves potential linker problems with "ftnname" since (by C
convention) the linker would attempt to resolve a reference to
"ftnname_".
.np
When calling C functions from FORTRAN, we need to instruct the
compiler to add the underscore at the end of the function name, and to
convert the name to lower case.
Since the FORTRAN compiler automatically converts identifiers to
uppercase, it is necessary to force the compiler to emit an equivalent
lowercase name.
Both of these things can be done with the following FORTRAN auxiliary
pragma:
.millust begin
*$pragma aux CNAME "!_"
.millust end
.np
There is another less convenient way to do this as shown in the
following:
.millust begin
*$pragma aux CNAME "cname_"
.millust end
.np
In the latter example, the case of the name in quotation marks is
preserved.
.np
Use of these pragmas resolves the naming differences, however, the
issue of argument passing must still be resolved.
.*
.section Argument Passing Convention
.*
.np
.ix 'mixed-language programming' 'argument passing'
.ix 'mixed-language programming' 'parameter passing'
In general, C uses call-by-value (passes argument values) while
FORTRAN uses call-by-reference (passes pointers to argument values).
This implies that to pass arguments to a FORTRAN subprogram we must
pass the addresses of arguments rather than their values.
C uses the "&" character to signify "address of".
.exam begin
result = ftnname( &arg );
.exam end
.np
When calling a C function from FORTRAN, the pragma used to correct the
naming conventions must also instruct the compiler that the C function
is expecting values, not addresses.
.millust begin
*$pragma aux CNAME "!_" parm (value)
.millust end
.np
The "parm (value)" addition instructs the FORTRAN compiler to pass
values, instead of addresses.
.np
Character data (strings) are an exception to the general case when
used as arguments.
In C, strings are not thought of as a whole entity, but rather as an
"array of characters".
Since strings are not considered scalar arguments, they are referenced
differently in both C and FORTRAN.
This is described in more detail in a following section.
.*
.section Memory Model Compatibility
.*
.np
.ix 'mixed-language programming' 'memory models'
While it is really not an issue with the 32-bit compilers (both use
the default "flat" memory model), it is important to know that the
default memory model used in &watf applications is the "large" memory
model ("ml") with "medium" and "huge" memory models as options.
Since the 16-bit &watc default is the "small" memory model, you must
specify the correct memory model when compiling your C/C++ code with
the 16-bit C or C++ compiler.
.*
.section Linking Considerations
.*
.np
.ix 'mixed-language programming' 'linking issues'
When both C/C++ and FORTRAN object files are combined into an
executable program or dynamic link library, it is important that you
list a least one of the FORTRAN object files first in the &lnkname
(&lnkcmdup) "FILES" directive to guarantee the proper search order
of the FORTRAN and C run-time libraries.
If you place a C/C++ object file first, you may inadvertently cause
the wrong version of run-time initialization routines to be loaded by
the linker.
.*
.section Integer Type Compatibility
.*
.np
.ix 'mixed-language programming' 'integer type'
In general, the number of bytes used to store an integer type is
implementation dependent.
In FORTRAN, the default size of an integer type is always 4 bytes,
while in C/C++, the size is architecture dependent.
The size of an "int" is 2 bytes for the 16-bit &watc compilers and 4
bytes for the 32-bit compilers while the size of a "long" is 4 bytes
regardless of architecture.
It is safest to prototype the function in C, specifying exactly what
size integers are being used.
The byte sizes are as follows:
.autopoint
.point
LONG - 4 bytes
.point
SHORT - 2 bytes
.endpoint
.np
Since FORTRAN uses a default of 4 bytes, we should specify the "long"
keyword in C for integer types.
.exam begin
long int ftnname( long int *, long int *, long int * );
.exam end
.np
In this case, "ftnname" takes three "pointers to long ints" as
arguments, and returns a "long int".
By specifying that the arguments are pointers, and not values, and by
specifying "long int" for the return type, this prototype has solved
the problems of argument passing and integer type compatibility.
.*
.section How do I pass integers from C to a FORTRAN function?
.*
.np
.ix 'mixed-language programming' 'passing integers'
The following &watc routine passes three integers to a FORTRAN
function that returns an integer value.
.millust begin
/* MIX1C.C - This C program calls a FORTRAN function to
* compute the max of three numbers.
*
* Compile/Link: wcl /ml mix1c mix1f.obj /fe=mix1
* wcl386 mix1c mix1f.obj /fe=mix1
*/
#include <stdio.h>
#pragma aux tmax3 "^";
long int tmax3( long int *, long int *, long int * );
.millust break
void main()
{
long int result;
long int i, j, k;
i = -1;
j = 12;
k = 5;
result = tmax3( &i, &j, &k );
printf( "Maximum is %ld\n", result );
}
.millust end
.*
.np
The FORTRAN function:
.millust begin
* MIX1F.FOR - This FORTRAN function accepts three integer
* arguments and returns their maximum.
* Compile: wfc[386] mix1f.for
integer function tmax3( arga, argb, argc )
integer arga, argb, argc
.millust break
tmax3 = arga
if ( argb .gt. tmax3 ) tmax3 = argb
if ( argc .gt. tmax3 ) tmax3 = argc
end
.millust end
.*
.section How do I pass integers from FORTRAN to a C function?
.*
.np
.ix 'mixed-language programming' 'passing integers'
The following &watf routine passes three integers to a &watc
function that returns an integer value.
.millust begin
* MIX2F.FOR - This FORTRAN program calls a C function to
* compute the max of three numbers.
*
* Compile/Link: wfl[386] mix2f mix2c.obj /fe=mix2
*$pragma aux tmax3 "!_" parm (value)
program mix2f
integer*4 tmax3
integer*4 result
integer*4 i, j, k
.millust break
i = -1
j = 12
k = 5
result = tmax3( i, j, k )
print *, 'Maximum is ', result
end
.millust end
.np
The C function "tmax3" is shown below.
.millust begin
/* MIX2C.C - This C function accepts 3 integer arguments
* and returns their maximum.
*
* Compile: wcc /ml mix2c
* wcc386 mix2c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -