Calling program functions from C
It is possible to call a BDL function from a C-Extension function.
To call a BDL function from a C-Extension function,
use the
fgl_call
macro:fgl_call ( function-name, nb-params );
In this call, function-name is the name of the program function to call, and nb-params is the number of parameters pushed on the stack for the program function. The function-name must be written in lowercase letters; the fglcomp compiler converts all program function names to lowercase.
The fgl_call()
macro is converted to a function that returns the number of
values returned on the stack.
Important: Parameters and return values must be pushed/popped on the runtime stack, by
using the stack functions. Parameters passed to the
BDL function must be pushed in the same order as the BDL parameter list:
push A, B, C =>
FUNCTION fct( A, B, C )
. However, values returned from the BDL function must be popped in
the reverse order of the BDL return clause: RETURN A, B, C => pop C, B, A
.The myprog.4gl BDL module defining the MAIN
block and the
display_item()
function to be called from the C extension:
IMPORT mycext
MAIN
CALL c_fct()
END MAIN
FUNCTION display_item(name, size)
DEFINE name VARCHAR(30), size INTEGER
DISPLAY name, size
RETURN length(name), (size / 100)
END FUNCTION
The mycext.c C extension module calling the BDL function:
#include <stdlib.h>
#include <stdio.h>
#include "f2c/fglExt.h"
int c_fct( int n );
UsrFunction usrFunctions[]={
{"c_fct",c_fct,0,0},
{0,0,0,0}
};
int c_fct( int n )
{
int rc, len;
float size2;
if (n != 0) exit(1);
pushquote("Hand gloves", 11);
pushint(54);
rc = fgl_call( display_item, 2 );
if (rc != 2) exit(1);
popflo(&size2);
popint(&len);
printf(">> %d %f\n", len, size2);
return 0;
}
Compilation and execution example on a Linux®
system:
$ fglmkext -o mycext.so mycext.c
$ fglcomp myprog.4gl
$ fglrun myprog.42m
Hand gloves 54
>> 11 0.540000