[racket] Foray into ffi/unsafe, nudge needed
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