Calling HP C from HP Pascal [ HP Pascal/iX Programmer's Guide ] MPE/iX 5.0 Documentation
HP Pascal/iX Programmer's Guide
Calling HP C from HP Pascal
The table and example in this section assume that the HP Pascal program
and the C routine that it calls are both compiled in Native Mode. If the
C routine is in a Compatibility Mode SL instead, you must write a switch
stub to access it from your HP Pascal program (see "Switch Stubs" ).
For more information on C types, please refer to the HP C Programmer's
Guide.
Table 9-1 matches corresponding HP Pascal and C types. It contains
only the types that are acceptable for formal intrinsic parameters. The
variable n is an integer.
Table 9-1. Corresponding HP Pascal and HP C Types
--------------------------------------------------------------------------------------------
| | |
| HP Pascal Type | Corresponding HP C Types |
| | |
--------------------------------------------------------------------------------------------
| | |
| Array: Not PACKED | Array of corresponding type1 |
| | |
--------------------------------------------------------------------------------------------
| | |
| Array: PACKED | Array of corresponding type1 |
| | |
--------------------------------------------------------------------------------------------
| | |
| Bit16 | unsigned short |
| | |
--------------------------------------------------------------------------------------------
| | |
| Bit32 | unsigned int |
| | |
--------------------------------------------------------------------------------------------
| | |
| Bit52 | struct with two unsigned ints |
| | |
--------------------------------------------------------------------------------------------
| | |
| Boolean (false = 0, true = 1) | Character or integer (false = 0, true |
| | <> 0)2 |
| | |
--------------------------------------------------------------------------------------------
| | |
| Char | unsigned char |
| | |
--------------------------------------------------------------------------------------------
| | |
| Enumerated 256 or fewer elements | unsigned char3 |
| | |
--------------------------------------------------------------------------------------------
| | |
| Enumerated 257 or more elements | unsigned short or int3 |
| | |
--------------------------------------------------------------------------------------------
| | |
| File | Not available8 |
| | |
--------------------------------------------------------------------------------------------
| | |
| Function | Function |
| | |
--------------------------------------------------------------------------------------------
| | |
| Function parameter or variable | Pass a pointer that references a C |
| | function6 |
| | |
--------------------------------------------------------------------------------------------
| | |
| Integer | int or long |
| | |
--------------------------------------------------------------------------------------------
| | |
| Longint | struct with two unsigned ints |
| | |
--------------------------------------------------------------------------------------------
| | |
| Longreal | double or long float |
| | |
--------------------------------------------------------------------------------------------
| | |
| PAC of n characters | Array of char, index = 1..n-1 |
| | |
--------------------------------------------------------------------------------------------
| | |
| Pointer: Not EXTNADDR | Pointer to corresponding type |
| | |
--------------------------------------------------------------------------------------------
| | |
| Pointer: EXTNADDR | Long ptr to corresponding type7 |
| | |
--------------------------------------------------------------------------------------------
| | |
| Procedure | void function |
| | |
--------------------------------------------------------------------------------------------
| | |
| Procedure parameter or variable | Pass a pointer that references a C |
| | function6 |
| | |
--------------------------------------------------------------------------------------------
| | |
| Real | float9 |
| | |
--------------------------------------------------------------------------------------------
| | |
| Record | struct or union4 |
| | |
--------------------------------------------------------------------------------------------
Table 9-1. Corresponding HP Pascal and HP C Types (cont.)
--------------------------------------------------------------------------------------------
| | |
| HP Pascal Type | Corresponding HP C Types |
| | |
--------------------------------------------------------------------------------------------
| | |
| Set | Not available |
| | |
--------------------------------------------------------------------------------------------
| | |
| Shortint | short |
| | |
--------------------------------------------------------------------------------------------
| | |
| String | char *5 |
| | |
--------------------------------------------------------------------------------------------
| | |
| String[n] | char *5 |
| | |
--------------------------------------------------------------------------------------------
| | |
| VAR parameter: Not EXTNADDR | Pointer to parameter |
| | |
--------------------------------------------------------------------------------------------
| | |
| VAR parameter: EXTNADDR | Long pointer to parameter7 |
| | |
--------------------------------------------------------------------------------------------
| | |
| 0..65535 | unsigned short |
| | |
--------------------------------------------------------------------------------------------
Table 9-1 Notes
1. The lower bound of an HP Pascal array can be any integer, but the
lower bound of a C array must be zero.
2. HP Pascal allocates one byte for a Boolean variable. It stores
the value in the rightmost bit.
3. A C enumerated variable corresponds to an HP Pascal integer, but
an HP Pascal enumerated variable corresponds to a C unsigned char
if it is one byte, a C unsigned short if it is two bytes, and a C
unsigned int if it is four bytes.
4. A C union type corresponds to the variant part of an HP Pascal
record type. For example:
The C type union
typedef union
{
int In ;
real Re ;
unsigned char Ch ;
} UnionType ;
corresponds to the untagged HP Pascal record variant
UnionType = RECORD CASE integer OF
1 : (In : integer) ;
2 : (Re : real) ;
3 : (Ch : char) ;
END ;
while the tagged HP Pascal record variant
Tagged_UnionType = RECORD CASE Tag : integer OF
1 : (In : integer) ;
2 : (Re : real) ;
END ;
corresponds to the C struct type
typedef struct
{
Tag : int ;
union
{
int : In ;
float : Re ;
}
} Tagged_UnionType ;
5. The value of an HP C variable of type (char *) ends with a NULL.
The HP Pascal type string[n], where n is the maximum length,
corresponds to the HP C type (char *), but has a different layout.
HP Pascal treats string parameters to external C routines
differently. Just before the call to the C routine, HP Pascal
puts a NULL character after the current length of the HP Pascal
string parameter. The address sent to the C routine is that of
the data part of the HP Pascal string parameter. When the C
routine returns to the HP Pascal program, HP Pascal strips the
NULL character from the HP Pascal string and updates its current
length.
6. To pass an actual parameter of this type to a C routine, declare
the formal parameter in the EXTERNAL declaration to be of type
integer (in the Pascal compilation unit that makes the call).
Before calling the C routine, call the predefined function
waddress to get the integer address of the Pascal routine. Pass
the integer address to the C routine. For example:
A C function:
int Signal (Sig , Func)
int Sig ;
int (*Func) () ; /* functional parameter */
{
...
}
A portion of the HP Pascal program that calls the C function:
{ EXTERNAL declaration for C function Signal }
FUNCTION Signal (Sig : integer ; Func : integer) ;
EXTERNAL C ;
{ Procedure whose address is passed to C function Signal }
PROCEDURE Signal_Handler (Sig : integer) ;
BEGIN
...
END ;
BEGIN { main program }
{ Actual call to C function Signal }
Dummy := Signal(3 , waddress(Signal_Handler) ) ;
END .
7. Declaring a long pointer in C is analogous to declaring an
ordinary pointer in Pascal, except that the "*" is replaced by
"^". For example,
int Func (Rec)
struct Stat ^Rec ;
declares Rec to be a VAR $EXTNADDR$ of type Stat.
8. Limited compatibility exists if the callee is written in C to do
raw I/O (using read(2) or write(2)) on a Pascal file. Such
functions can be called from Pascal by passing the result of a
call to fnum(pascal_file) to the C function.
9. If you are passing a real parameter to a C routine that expects a
float you must compile the routine in ANSI mode or with the +r
option to the C compiler. This insures that floats are not
promoted to doubles. Otherwise, you should pass a longreal value.
(For more information refer to the HP C Programmer's Guide.
Example 1
The Pascal program Pascal_C calls the external C routine add, passing a
VAR parameter.
Pascal program:
PROGRAM Pascal_C (input,output);
VAR
int1,
int2,
int3 : integer;
PROCEDURE add ( parm1 : integer;
parm2 : integer;
VAR parm3 : integer); EXTERNAL C;
BEGIN
int1 := 25000;
int2 := 30000;
add(int1,int2,int3);
writeln(int3);
END.
C routine:
void add (a,b,c)
int a,b;
int *c;
{
*c = a + b;
}
Example 2
The Pascal program Pascal_C2 calls the external C routine cread. The
Pascal program passes a string parameter to the C routine.
Pascal program:
PROGRAM Pascal_C2 (output);
VAR
str : string[40];
FUNCTION c_read (VAR s : string) : Boolean; EXTERNAL C;
BEGIN
setstrlen(str,0);
IF c_read(str) THEN
writeln('str = ', str)
ELSE
writeln('couldn''t read str');
END.
C routine:
#include <stdio.h>
int c_read(s) /* no Boolean type in C */
char *s;
{
return (fgets(stdin,s) >= 0);
}
MPE/iX 5.0 Documentation