[plt-scheme] ffi type _bool does only return #t
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!