1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
#include <stdlib.h>
#include <stdio.h>
/*#include <string.h>
#include <ctype.h>*/
#include <assert.h>
#include <libfungw/fungw.h>
#include <libfungwbind/c/fungw_c.h>
double wrap_avg(fgw_ctx_t *ctx, double a, double b);
/* Import fawk init; this relies on two things:
- fawk is always available in fungw, no external dep (well, the user can
disable it in ./configure that'd lead to link error here)
- fawk is in the big static lib (.a) of all languages and if we call its
init, all relevant objects will get linked
*/
extern int pplg_init_fungw_fawk(void);
int main(int argc, char *argv[])
{
fgw_ctx_t ctx;
fgw_arg_t res, arg[8];
fgw_error_t err;
fgw_obj_t *sobj;
fgw_func_t *func_avg;
char *sres;
/* Initialize and register the script language engine fawk */
pplg_init_fungw_fawk();
/* initialize a context */
fgw_init(&ctx, "host");
/* create objects for the script: loads script and runs its main() */
sobj = fgw_obj_new(&ctx, "avg_script", "fawk", "avg.fawk", NULL);
assert(sobj != NULL);
/* Get a function handle knowing the short name of the function */
func_avg = fgw_func_lookup(&ctx, "avg");
if (func_avg == NULL) {
fprintf(stderr, "Error: failed to find global function avg\n");
return 1;
}
/* Manual call: no helper, just raw call to the function pointer */
arg[0].type = FGW_FUNC;
arg[0].val.argv0.func = func_avg;
arg[0].val.argv0.user_call_ctx = NULL;
arg[1].type = FGW_DOUBLE;
arg[1].val.nat_double = 42;
arg[2].type = FGW_DOUBLE;
arg[2].val.nat_double = 71;
err = func_avg->func(&res, 3, arg);
printf("direct: err=%d rt=%x rv=%.2f\n", err, res.type, res.val.nat_double);
/* Dtring based call. The callee gets each argument as a string
(in this particular case the callee will convert them to double within
fawk by doing arithmetics on them). Result is always an allocated
(char *) string (so fungw will convert the script returned double
to a newly allocated string). This slow calling convention may be
useful if input and output is string based for some reason, e.g.
when implementing a CLI. */
sres = fgw_scall(&ctx, "avg", "42", "71", NULL);
printf("scall: sres='%s'\n", sres);
free(sres);
/* Type/data based call, using generic vararg wrapper; this saves all the
unnecessary string conversions in this example. Of course any argument
may be passed as a different type, even a string, if that's what is
available at a time - the script binding code or the script will
do the necessary conversion. Since this is a script, we shouldn't rely
on the return value type being double - rather convert it. If it is
a double, the conversion is a noop. Note: in vararg calls, numeric args
shall be explicitly casted: without the (double) cast here, these
numbers could easily pass as integers causing wrong readout on the other
side! */
err = fgw_vcall(&ctx, &res, "avg", FGW_DOUBLE, (double)42, FGW_DOUBLE, (double)71, 0);
fgw_arg_conv(&ctx, &res, FGW_DOUBLE);
printf("vcall: err=%d rt=%x rv=%.2f\n", err, res.type, res.val.nat_double);
/* Use local wrapper so the call feels native in C */
printf("wrap: %.2f\n", wrap_avg(&ctx, 42, 77));
/* clean up and exit */
fgw_uninit(&ctx);
fgw_atexit();
return 0;
}
/* Emulate a native C function: use the vararg based shorthand and convert
the result to double. The drawback of this overly simple API is the
inability of error reporting. Of course the code could check the return
value of fgw_vcall() and fgw_arg_conv() and report error. */
double wrap_avg(fgw_ctx_t *ctx, double a, double b)
{
fgw_arg_t res;
fgw_vcall(ctx, &res, "avg", FGW_DOUBLE, a, FGW_DOUBLE, b, 0);
fgw_arg_conv(ctx, &res, FGW_DOUBLE);
return res.val.nat_double;
}
|