* Generated by setuputil.sno setup.makeinclude() 04/30/2025 15:14:54
	FFI_DL = "ffi"
**=pea
**=sect NAME
**snobol4ffi \- Foreign Function Interface for SNOBOL4
**=sect SYNOPSYS
**=code
**-INCLUDE 'ffi.sno'
**        dl = FFI_DLOPEN("/usr/lib/libm.so")
**        sym = FFI_DLSYM(dl, "hypot")
**        DEFINE_FFI("hypot(double,double)double", sym)
**        OUTPUT = hypot(3, 4)
**=ecode
**=sect DESCRIPTION
**=cut
	LOAD("FFI_PREP_CIF(STRING)", FFI_DL)
	LOAD("FFI_CALL(EXTERNAL,EXTERNAL)", FFI_DL)
	LOAD("FFI_FREE_CIF(EXTERNAL)STRING", FFI_DL)
**=pea
**=item B<FFI_DLOPEN(>I<filename>B<)>
**takes the path of a dynamicly loadable
**executable file and returns a value
**which can be passed to B<FFI_DLSYM()>.
**
**=cut
	LOAD("FFI_DLOPEN(STRING)", FFI_DL)
**=pea
**=item B<FFI_DLSYM(>I<library>,I<function>B<)>
**takes a I<library> value
**returned by B<FFI_DLOPEN()>, and a function name, and returns a
**value which can be passed to B<DEFINE_FFI()>.
**=cut
	LOAD("FFI_DLSYM(,STRING)", FFI_DL)
	LOAD("FFI_RTLD_NEXT()", FFI_DL)
	LOAD("FFI_RTLD_DEFAULT()", FFI_DL)
	LOAD("FFI_RTLD_SELF()", FFI_DL)
**** funcs.sno:
* $Id: funcs.sno,v 1.14 2020-08-08 22:54:46 phil Exp $
**=pea
**=item B<DEFINE_FFI(>I<prototype>,I<pointer>B<)>
**defines a SNOBOL4 function that calls an external function via B<ffi>(3).
**I<prototype> contains a string name for the function followed
**by a comma separated list of parameter types inside of parenthesis
**(any of:
**B<sint8>, B<sint16>, B<sint32>, B<sint64>,
**B<uint8>, B<uint16>, B<uint32>, B<uint64>,
**B<schar>, B<sshort>, B<sint>, B<slong>,
**B<uchar>, B<ushort>, B<uint>, B<ulong>,
**B<float>, B<double>, B<longdouble>, B<pointer>),
**followed by a return type, which can be
**any of the above parameter types, or
**B<void>, B<string>, B<freestring>.
**I<pointer> is a value returned by B<FFI_DLSYM()>.
**=cut
-include 'unique.sno'
	DEFINE("DEFINE_FFI(proto,ptr)func,args,tmp,i,cifvar,ptrvar,,dummies")
						     :(define_ffi.end)
define_ffi
	proto pos(0) break('(') . fname (bal . args rem) . proto
+						:f(FRETURN)
*	output = fname
*	output = proto
*	output = args
	i = 0
	tmp = args ','
define_ffi.loop
	tmp pos(0) break(',') ',' =		:f(define_ffi.eloop)
	dummies = dummies ',a' (i = i + 1)	:(define_ffi.loop)
define_ffi.eloop
	cifvar = UNIQUE()
	ptrvar = UNIQUE()
	$cifvar = FFI_PREP_CIF(proto)		:f(FRETURN)
	$ptrvar = ptr
	tmp = fname ' ' fname ' = FFI_CALL(' cifvar ',' ptrvar dummies ') '
+						':f(FRETURN)s(RETURN)'
*	output = tmp
	CODE(tmp)				:f(FRETURN)
	dummies pos(0) ',' =
	tmp = fname '(' dummies ')'
*	output = tmp
	DEFINE(tmp)				 :f(FRETURN)s(RETURN)
define_ffi.end

**=pea
**=sect SEE ALSO
**B<snobol4>(1), B<ffi>(3), B<dlopen>(3)
**=sect AUTHOR
**Philip L. Budne
**=break
**Inspired by an FFI interface by Fred Weigel
**=cut
******** end funcs.sno
**************** end ffi.sno
