Hello,
As I've noticed, the compatibility layer of cffi to uffi has a couple of problems. For that reason it does not work with elephant out of the box. I intend trying to address these problems and send patches afterwards.
I'm using SBCL. It seems to me that one of the problems it that functions defined with (original) uffi accepts aliens and saps as pointer arguments, while cffi (and uffi-compat) only work with saps, right? Another problems seems to be that uffi's def-function accepts :out arguments, unlike cffi's defcfun. Such arguments are not passed when you call the wrapper function, the wrapper automatically pass foreign-allocated pointers to the C function which is supposed to put some value in that pointer. Then the wrapper function returns the values inserted by the C function as multiple values (starting from the second value).
I intend to adapt uffi-compat's functions to unwrap aliens into saps. That is implementation dependent, so I was thinking about putting one function named unwrap-typed-pointer in cffi-sys and also put an entry in the documentation for other implementations (that have typed pointers like SBCL's aliens) to possibly implement this function as well. That function would only be used in uffi-compat, not in cffi.
Now, about :out arguments, wouldn't it be nice if cffi supports this as well? Currently many projects have to do this by hand, why not abstract it away? That would also make elephant portable to cffi more easily. The list of arguments of defcfunhttp://common-lisp.net/project/cffi/manual/html_node/defcfun.html#defcfunwould become
arguments ::= { (arg-name arg-type [direction]) }*
where direction could be :in (the default) or :out. In case it's :out, the argument should not be passed to the function, like in uffi. Other possible options are :copy and :in-out like sbcl's define-alien-routinehttp://www.sbcl.org/manual/#The-define_002dalien_002droutine-Macro .
Any thoughts are appreciated.
Regards, Gustavo.
2010/7/13 Gustavo gugamilare@gmail.com:
As I've noticed, the compatibility layer of cffi to uffi has a couple of problems. For that reason it does not work with elephant out of the box. I intend trying to address these problems and send patches afterwards.
IIRC, elephant doesn't work with uffi-compat because it grossly breaks UFFI's abstractions and mixes sb-alien code with UFFI code.
I'm using SBCL. It seems to me that one of the problems it that functions defined with (original) uffi accepts aliens and saps as pointer arguments, while cffi (and uffi-compat) only work with saps, right?
UFFI might not accept saps, I don't remember. But, it should be an implementation detail if one sticks to the UFFI API.
Another problems seems to be that uffi's def-function accepts :out arguments, unlike cffi's defcfun. Such arguments are not passed when you call the wrapper function, the wrapper automatically pass foreign-allocated pointers to the C function which is supposed to put some value in that pointer. Then the wrapper function returns the values inserted by the C function as multiple values (starting from the second value).
UFFI seems to pass :out along on SBCL/CMUCL/SCL but not other Lisps (IIUC) and it's not documented.
I intend to adapt uffi-compat's functions to unwrap aliens into saps. That is implementation dependent, so I was thinking about putting one function named unwrap-typed-pointer in cffi-sys and also put an entry in the documentation for other implementations (that have typed pointers like SBCL's aliens) to possibly implement this function as well. That function would only be used in uffi-compat, not in cffi.
If this is stricly due to Elephant, I'd rather have Elephant itself fixed. If that's not possible, I'd keep that confined to uffi-compat at least until we can think of other use cases for an unwrap-typed-pointer function.
I don't remember if Elephant also assumes that aliens will be returned; that would be problematic as well.
Now, about :out arguments, wouldn't it be nice if cffi supports this as well? Currently many projects have to do this by hand, why not abstract it away? That would also make elephant portable to cffi more easily. The list of arguments of defcfun would become
arguments ::= { (arg-name arg-type [direction]) }*
where direction could be :in (the default) or :out. In case it's :out, the argument should not be passed to the function, like in uffi. Other possible options are :copy and :in-out like sbcl's define-alien-routine.
That'd be a nice feature indeed. Stephen Compall implemented it at one point: http://article.gmane.org/gmane.lisp.cffi.devel/987. That code doesn't compile anymore and it's probably not as integrated into defcfun as you'd wish.
Let us know if you need any help.
Cheers,
Hello, again,
I've added support for :out, :in-out and :copy direction arguments except for defcfun with &rest args. The patch is attached, it includes some tests. Anyone may feel free to add more tests if it is convenient.
For defcfun with &rest arguments, I still need to test so I didn't include it in my patch. I'll do that tomorrow.
Changing subject, I noted that, *without* my changes, there are 4 unexpected failures with cffi in my system (and 2 expected).
The tests FUNCALL.VARARGS.DOUBLE, DEFCFUN.VARARGS.FLOAT, DEFCFUN.VARARGS.DOUBLE fail because of localization issues. Here in Brazil, we write "3,14" instead of "3.14" and sprintf takes that into account. Not a big problem, though, just notifying.
The test DEFCFUN.BFF.2 fails, I suspect it is because of the precision of doubles. The function returns the first, the second is expected.
7758614624042983568 7758614658402721936
The expected failures are STRING.ENCODING.UTF-16.BASIC and STRING.ENCODINGS.ALL.BASIC.
SBCL 1.0.40, 32-bit Ubuntu.
Now, except for those tests that were already failing, my changes didn't fail even a single one of them :)
Gustavo.
Hello,
Sorry, my definition of "tomorrow" and "day duration" is a little distorted :3
My previous patch was kind of messy, so I decided to restart everything from the concept. Instead of the argument directions to be handled by the macro expansion and (complicated) auxiliary functions, it is now handled (mainly) by translate-objects and expand-to-foreign-dyn.
Also, tests for varargs functions are a bit hackish because I don't know how to create a C function with variadic argument. I don't know if it will work on all systems. Anyway, the tests are there, just test them and see if they work ;)
Gustavo.
Em 14 de julho de 2010 23:01, Gustavo gugamilare@gmail.com escreveu:
Hello, again,
I've added support for :in, :out, :in-out and :copy direction arguments except for defcfun with &rest args. The patch is attached, it includes some tests. Anyone may feel free to add more tests if it is convenient.
For defcfun with &rest arguments, I still need to test so I didn't include it in my patch. I'll do that tomorrow.
Changing subject, I noted that, *without* my changes, there are 4 unexpected failures with cffi in my system (and 2 expected).
The tests FUNCALL.VARARGS.DOUBLE, DEFCFUN.VARARGS.FLOAT, DEFCFUN.VARARGS.DOUBLE fail because of localization issues. Here in Brazil, we write "3,14" instead of "3.14" and sprintf takes that into account. Not a big problem, though, just notifying.
The test DEFCFUN.BFF.2 fails, I suspect it is because of the precision of doubles. The function returns the first, the second is expected.
7758614624042983568 7758614658402721936
The expected failures are STRING.ENCODING.UTF-16.BASIC and STRING.ENCODINGS.ALL.BASIC.
SBCL 1.0.40, 32-bit Ubuntu.
Now, except for those tests that were already failing, my changes didn't fail even a single one of them :)
Gustavo.
Hello, again,
I found one inconsistency in uffi's documentation. Uffi's doc says that dereferencing types :char and :unsigned-char return characters where actually it returns integers (at least here). Cffi's uffi-compat follows the doc and that also breaks elephant. Sending a new patch that "fix" that and also has a change necessary to def-function accept directions.
Please let me know whether my patches will get into cffi or if there is something I should change in them.
Now off to find more errors...
Gustavo.
Em 6 de agosto de 2010 11:19, Gustavo gugamilare@gmail.com escreveu:
Hello,
Sorry, my definition of "tomorrow" and "day duration" is a little distorted :3
My previous patch was kind of messy, so I decided to restart everything from the concept. Instead of the argument directions to be handled by the macro expansion and (complicated) auxiliary functions, it is now handled (mainly) by translate-objects and expand-to-foreign-dyn.
Also, tests for varargs functions are a bit hackish because I don't know how to create a C function with variadic argument. I don't know if it will work on all systems. Anyway, the tests are there, just test them and see if they work ;)
Gustavo.
Em 14 de julho de 2010 23:01, Gustavo gugamilare@gmail.com escreveu:
Hello, again,
I've added support for :in, :out, :in-out and :copy direction arguments except for defcfun with &rest args. The patch is attached, it includes some tests. Anyone may feel free to add more tests if it is convenient.
For defcfun with &rest arguments, I still need to test so I didn't include it in my patch. I'll do that tomorrow.
Changing subject, I noted that, *without* my changes, there are 4 unexpected failures with cffi in my system (and 2 expected).
The tests FUNCALL.VARARGS.DOUBLE, DEFCFUN.VARARGS.FLOAT, DEFCFUN.VARARGS.DOUBLE fail because of localization issues. Here in Brazil, we write "3,14" instead of "3.14" and sprintf takes that into account. Not a big problem, though, just notifying.
The test DEFCFUN.BFF.2 fails, I suspect it is because of the precision of doubles. The function returns the first, the second is expected.
7758614624042983568 7758614658402721936
The expected failures are STRING.ENCODING.UTF-16.BASIC and STRING.ENCODINGS.ALL.BASIC.
SBCL 1.0.40, 32-bit Ubuntu.
Now, except for those tests that were already failing, my changes didn't fail even a single one of them :)
Gustavo.
2010/8/10 Gustavo gugamilare@gmail.com:
I found one inconsistency in uffi's documentation. Uffi's doc says that dereferencing types :char and :unsigned-char return characters where actually it returns integers (at least here).
Does that mean these tests fail for you? http://git.b9.com/?p=uffi.git;a=blob;f=tests/objects.lisp