[geos-devel] Ruby, FFI and ERROR_/NOTICE_MESSAGE

Sean Gillies sean.gillies at gmail.com
Thu Dec 9 12:32:12 EST 2010


On Wed, Dec 8, 2010 at 10:34 PM, J Smith <dark.panda+lists at gmail.com> wrote:
> On Thu, Dec 9, 2010 at 12:09 AM, Charlie Savage <cfis at savagexi.com> wrote:
>>> I believe that the crux of the problem may be due to GEOS's error
>>> handlers using varargs, which libffi cannot handle in callbacks
>>> according to its documentation.
>>
>> Just did a quick read of https://github.com/ffi/ffi/wiki/examples and the
>> google group. Seems like in general FFI does support varargs.  Are callbacks
>> a special case that isn't handled?  How hard do you suppose to get them to
>> work?
>>
>
> I think callbacks are a special case, although the documentation is
> somewhat vague. In the Missing Features section of the info
> documentation, it says:
>
> "There is no support for calling varargs functions.  This may work on
> some platforms, depending on how the ABI is defined, but it is not
> reliable."
>
> I believe this is referring to callbacks. When setting up a callback
> along these lines...
>
> attach_function(:initGEOS_r, callback([ :string, :varargs ], :void), :void)
> ...
> FFIGeos.initGEOS_r(
>  self.method(:error_handler),
>  self.method(:error_handler)
> )
> ...
> def error_handler(*args)
>  p(args)
> end
>
> All you get for the varargs argument is nil and the segfaults and
> weirdness occurs as before. It appears that this is a special case, I
> guess.
>
> Another option beyond modifying GEOS directly might be to write a
> small native C shim between the CAPI and Ruby and access the error
> messages through that. It might not be ideal, as I think it would be
> preferable to keep the library purely Ruby, but it would be an option
> that wouldn't affect the CAPI or cause any binary compatibility breaks
> should the context handler need to be changed.
>
> I'll ask around the FFI groups and see what turns up.
>
> Cheers!

FWIW, here's the GeoDjango approach:

  http://code.djangoproject.com/browser/django/trunk/django/contrib/gis/geos/libgeos.py#L53

and the Shapely approach:

  https://github.com/sgillies/shapely/blob/master/shapely/geos.py#L148

Shapely by default takes the error messages and sends them to
/dev/null because I didn't find them super useful. Each of the above
use a callback factory from ctypes

  http://docs.python.org/library/ctypes.html#callback-functions


More information about the geos-devel mailing list