[racket] Foray into ffi/unsafe, nudge needed

From: John Clements (clements at brinckerhoff.org)
Date: Fri Aug 30 14:23:09 EDT 2013

On Aug 30, 2013, at 9:50 AM, Peter Schmiedeskamp wrote:

> Dear list,
> 
> I thought it would be an interesting exercise to learn something about Racket and FFI by wrapping libgeos (http://trac.osgeo.org/geos/) similar to what the R people have done (http://cran.r-project.org/web/packages/rgeos/index.html).
> 
> Right out of the gate, I seem to be stuck, and am hoping for a nudge forward. The C library requires initialization before all else, and in turn that initialization function takes two pointers to two callback logging functions (from geos_c.h):
> 
> 
> /* what a message handler looks like */
> typedef void (*GEOSMessageHandler)(const char *fmt, ...);
> 
> /* what the call to initGEOS() looks like */
> extern void GEOS_DLL initGEOS(GEOSMessageHandler notice_function, GEOSMessageHandler error_function);
> 
> 
> I found examples in Python and in C (included in the R version) where they had created these functions and plumbed them into the logging infrastructure:
> 
> # Python
> NOTICEFUNC = CFUNCTYPE(None, c_char_p, c_char_p)
> def notice_h(fmt, lst):
>     fmt, lst = fmt.decode(), lst.decode()
>     try:
>         warn_msg = fmt % lst
>     except:
>         warn_msg = fmt
>     logger.warning('GEOS_NOTICE: %s\n' % warn_msg)
> notice_h = NOTICEFUNC(notice_h)
> 
> 
> /* C - RGeos */
> static void __warningHandler(const char *fmt, ...) {
> 
>     char buf[BUFSIZ], *p;
>     va_list(ap);
>     va_start(ap, fmt);
>     vsprintf(buf, fmt, ap);
>     va_end(ap);
>     p = buf + strlen(buf) - 1;
>     if(strlen(buf) > 0 && *p == '\n') *p = '\0';
> 
>     warning(buf);
>     
>     return;
> }
> 
> 
> 
> I've found _cprocedure, which says it can be used for callbacks to racket functions. After reading through that section in the docs a couple of times I'm still a bit murky on what that would look like. It would seem I need to create a c-callable function that: 
> 1. receives one or more 'char'
> 2. converts the char to a racket string
> 3. pass the string to 'log-FOO' depending on the severity

You may want to take a look at my portaudio package; it uses callbacks in (what I believe to be) the way you describe.

http://planet.racket-lang.org/display.ss?package=portaudio.plt&owner=clements

or just

https://github.com/jbclements/rack-portaudio


John



Posted on the users mailing list.