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
|
#include "EXTERN.h"
#include "perl.h"
#include "pdlcore.h"
#include <gsl/gsl_math.h>
#define PDL PDL_GSL_INTEG
extern Core *PDL;
#define max_nested_integrals 20
static SV* ext_funname[max_nested_integrals];
static int current_fun = -1;
void set_funname(SV *fn) {
current_fun++;
if (current_fun > (max_nested_integrals)) barf("Too many nested integrals, sorry!\n");
ext_funname[current_fun] = fn;
}
void dec_func() {
current_fun--;
}
void my_handler (const char * reason,
const char * file,
int line,
int gsl_errno){
printf("Warning: %s at line %d of GSL file %s\n",reason,line,file);
}
double FUNC(double x,void * p){
SV* funname;
int count;
I32 ax ;
double res;
double* resp;
dSP;
resp = &res;
ENTER;
SAVETMPS;
/* get function name on the perl side */
funname = ext_funname[current_fun];
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVnv(x)));
PUTBACK;
count=call_sv(funname,G_SCALAR);
SPAGAIN;
SP -= count ;
ax = (SP - PL_stack_base) + 1 ;
if (count!=1)
croak("error calling perl function\n");
/* recover output value */
/*res = POPn;*/
*resp = SvNV(ST(0));
PUTBACK;
FREETMPS;
LEAVE;
return res;
}
|