[plt-scheme] ffi type _bool does only return #t

From: Eli Barzilay (eli at barzilay.org)
Date: Thu Oct 12 09:38:05 EDT 2006

On Oct 12, Robert Matovinovic wrote:
> Hi,
> I'm currently working on the bindings of a dll using ffi. The
> library uses a lot of boolean procedures. I now found that the type
> _bool converts everything into #t when I call a function, thus
> making it useless. I read the documentation, where it is said _bool
> converts every #f into 0 _int and other values into 1, but shouldn't
> that apply also to the other way round?  Here is a very simple
> example: The dll exports the following procedure
> 
> bool YesNo(int n)
> {
> 	if(n == 0) return false;
> 	return true;
> }
> 
> On the scheme side the code is:
> (require (lib "foreign.ss" "mzlib"))
> (unsafe!)
> 
> (define dll (ffi-lib "Test"))
> (define yesno (get-ffi-obj "YesNo" dde-client-dll (_fun _int -> _bool)))
> 
> (yesno 0)
> (yesno 12)
> 
> The result is:
> Welcome to DrScheme, version 350.4-svn7jul2006.
> Language: Pretty Big (includes MrEd and Advanced Student) custom.
> #t
> #t

I tried this code on Linux, and it worked as expected -- but I
#defined `bool', `false', and `true' to `int', `0', `1'.  The problem
looks like bool being a byte on Windows.  (I think that usually `bool'
is an int.)


> If I substitute _bool with _byte in the get-ffi-obj call I get:
> Welcome to DrScheme, version 350.4-svn7jul2006.
> Language: Pretty Big (includes MrEd and Advanced Student) custom.
> 0
> 1
> > 
> 
> This shows the values are transferred right via ffi, but the type conversion
> goes wrong.

This confirms it.


> Do I miss anything? Is there a simple way to get the following
> behavior:
> (yesno 0)
> > #f
> (yesno 12)
> > #t

Yes -- you need to make a new foreign type, which is based on _byte.
This is very simple: you need to use `make-ctype' with _byte, and two
translations from boolean values to _byte (an integer) and back:

  (define _bytebool
    (make-ctype _byte
                (lambda (bool) (if boll 1 0))
                (lambda (byte) (not (zero? byte)))))

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!


Posted on the users mailing list.