📄 pgcmixf.gml
字号:
*/
long int tmax3( long int arga,
long int argb,
long int argc )
.millust break
{
long int result;
result = arga;
if( argb > result ) result = argb;
if( argc > result ) result = argc;
return( result );
}
.millust end
.*
.section How do I pass a string from a C function to FORTRAN?
.*
.np
.ix 'mixed-language programming' 'passing strings'
Character strings are referenced differently in C and FORTRAN.
The C language terminates its strings with a null character as an
End-Of-String (EOS) marker.
In this case, C need not store the length of the string in memory.
FORTRAN, however, does not use any EOS marker; hence it must store
each string's length in memory.
.np
The structure FORTRAN uses to keep track of character data is called a
"string descriptor" which consists of a pointer to the character data
(2, 4, or 6 bytes, depending on the data model)
followed by an unsigned integer length (2 bytes or 4 bytes, depending
on the data model).
.millust begin
system option size of pointer size of length
------ ------ --------------- --------------
16-bit /MM 16 bits 16 bits
16-bit /ML 32 bits 16 bits
32-bit /MF 32 bits 32 bits
32-bit /ML 48 bits 32 bits
.millust end
.pc
In order to access character data, FORTRAN needs to have access to the
data's string descriptor.
Hence, FORTRAN expects a pointer to a string descriptor to be passed
as an argument for character data.
.np
Passing string arguments between C and FORTRAN is a simple task of
describing a struct type in C containing the two fields described
above.
The first field must contain the pointer to the character data, and
the second field must contain the length of the string being passed.
A pointer to this structure can then be passed to FORTRAN.
.*
.millust begin
* MIX3F.FOR - This FORTRAN program calls a function written
* in C that passes back a string.
*
* Compile/Link: wfl[386] mix3f mix3c.obj /fe=mix3
program mix3f
character*80 sendstr
character*80 cstring
.millust break
cstring = sendstr()
print *, cstring(1:lentrim(cstring))
end
.millust end
.np
The C function "sendstr" is shown below.
.millust begin
/* MIX3C.C - This C function passes a string back to its
* calling FORTRAN program.
*
* Compile: wcc /ml mix3c
* wcc386 mix3c
*/
#include <string.h>
#pragma aux sendstr "^";
typedef struct descriptor {
char *addr;
unsigned len;
} descriptor;
.millust break
void sendstr( descriptor *ftn_str_desc )
{
ftn_str_desc->addr = "This is a C string";
ftn_str_desc->len = strlen( ftn_str_desc->addr );
}
.millust end
.*
.section How do I pass a string from FORTRAN to a C function?
.*
.np
.ix 'mixed-language programming' 'passing strings'
By default, FORTRAN passes the address of the string descriptor when
passing strings.
If the C function knows it is being passed a string descriptor
address, then it is very similar to the above example.
If the C function is expecting normal C-type strings, then a FORTRAN
pragma can be used to pass the string correctly.
When the &watf compiler pragma to pass by value is used for strings,
then just a pointer to the string is passed.
.exam begin
*$pragma aux cname "!_" parm (value)
.exam end
.np
The following example FORTRAN mainline defines a string, and passes it
to a C function that prints it out.
.millust begin
* MIX4F.FOR - This FORTRAN program calls a function written
* in C and passes it a string.
*
* Compile/Link: wfl[386] mix4f mix4c.obj /fe=mix4
*$pragma aux cstr "!_" parm (value)
program mix4f
character*80 forstring
.millust break
forstring = 'This is a FORTRAN string'//char(0)
call cstr( forstring )
end
.millust end
.np
The C function:
.millust begin
/* MIX4C.C - This C function prints a string passed from
* FORTRAN.
*
* Compile: wcc /ml mix4c
* wcc386 mix4c
*/
#include <stdio.h>
.millust break
void cstr( char *instring )
{
printf( "%s\n", instring );
}
.millust end
.*
.section How do I access a FORTRAN common block from within C?
.*
.np
.ix 'mixed-language programming' 'common blocks'
The following code demonstrates a technique for accessing a FORTRAN
common block in a C routine.
The C routine defines an extern struct to correspond to the FORTRAN
common block.
.*
.millust begin
* MIX5F.FOR - This program shows how a FORTRAN common
* block can be accessed from C.
*
* Compile/Link: wfl[386] mix5f mix5c.obj /fe=mix5
program mix5f
external put
common/cblk/i,j
.millust break
i=12
j=10
call put
print *, 'i = ', i
print *, 'j = ', j
end
.millust end
The C function:
.millust begin
/* MIX5C.C - This code shows how to access a FORTRAN
* common block from C.
*
* Compile: wcc /ml mix5c
* wcc386 mix5c
*/
#include <stdio.h>
#pragma aux put "^";
#pragma aux cblk "^";
.millust break
#ifdef __386__
#define FAR
#else
#define FAR far
#endif
extern struct cb {
long int i,j;
} FAR cblk;
.millust break
void put( void )
{
printf( "i = %ld\n", cblk.i );
printf( "j = %ld\n", cblk.j );
cblk.i++;
cblk.j++;
}
.millust end
.np
For the 16-bit C compiler, the common block "cblk" is described as
.kw far
to force a load of the segment portion of the address.
Otherwise, since the object is smaller than 32K (the default data
threshold), it is assumed to be located in the DGROUP group which is
accessed through the SS segment register.
.*
.section How do I call a C function that accepts a variable number of arguments?
.*
.np
.ix 'mixed-language programming' 'variable number of arguments'
One capability that C possesses is the ability to define functions
that accept variable number of arguments.
This feature is not present, however, in the definition of the FORTRAN
77 language.
As a result, a special pragma is required to call these kinds of
functions.
.millust begin
*$pragma aux printf "!_" parm (value) caller []
.millust end
.np
The "caller" specifies that the caller will pop the arguments from the
stack.
The "[]" indicates that there are no arguments passed in registers
because the
.mono printf
function takes a variable number of arguments passed on the stack.
The following example is a FORTRAN function that uses this pragma.
It calls the
.mono printf
function to print the value 47 on the screen.
.millust begin
* MIX6.FOR - This FORTRAN program calls the C
* printf function.
* Compile/Link: wfl[386] mix6
*$pragma aux printf "!_" parm (value) caller []
program mix6
.millust break
character cr/z0d/, nullchar/z00/
call printf( 'Value is %ld.'//cr//nullchar, 47 )
end
.millust end
.*
.np
For more information on the pragmas that are used extensively during
inter-language programming, please refer to the chapter entitled
"Pragmas" in both the
.us &watc User's Guide
and the
.us &watf User's Guide.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -