[Chicken-users] foreign: Why is passing structs as arguments and return-types not supported?
Hi guys! Reading the chicken docs on foreign, you'll find: Structs cannot be directly passed as arguments to foreign functions, nor can they be result values. ( http://api.call-cc.org/doc/foreign/types#def:struct) Pointers to structs are supported, but not structs-by-value. I am wondering if there are technical reason why this is the case, or if it's simply a missing feature. If it simply hasn't been implemented, I will see if I can make this feature. Thank you, K. ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] foreign: Why is passing structs as arguments and return-types not supported?
On Wed, 2012-02-29 at 14:07 +0100, Kristian Lein-Mathisen wrote: [...] Reading the chicken docs on foreign, you'll find: Structs cannot be directly passed as arguments to foreign functions, nor can they be result values. (http://api.call-cc.org/doc/foreign/types#def:struct) Pointers to structs are supported, but not structs-by-value. I am wondering if there are technical reason why this is the case, or if it's simply a missing feature. [...] Hello, there are several reasons why few foreign function interfaces out there support this. The most compelling reason maybe is that it is not strictly necessary to support this feature and hence it adds no real value. For example, let's assume we have a C library with an interface like this: typedef struct Dosh { int foo, bar; } Dosh; void distim(Dosh d); Now if we want a CHICKEN binding for that it's easy to write: (define distim (foreign-lambda* void (((c-pointer Dosh) d)) distim(*d);)) Just use a pointer argument, dereference it on the C side and you're done! Another reason why structure types would not be all that useful is that the canonical representation of C structures on the CHICKEN side would be foreign pointers to blocks of memory anyway. Plus most C ABIs pass most structure arguments by reference anyway. So supporting an additional class of types that would effectively map to the same constructs on both sides of the FFI would be redundant and could even be considered needlessly confusing. Last but not least, passing structures as pointers makes memory management for them explicit and that is a good thing in this case because there is simply no way the FFI could automatically figure out how the optimal memory management strategy for structures passed by value should look like. For example, whether such a structure can be allocated as an atomic block of memory or not is impossible to answer without knowing what the functions producing and consuming instances of the structure actually do. Ciao, Thomas -- When C++ is your hammer, every problem looks like your thumb. ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] foreign: Why is passing structs as arguments and return-types not supported?
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 02/29/2012 01:29 PM, Thomas Chust wrote: Last but not least, passing structures as pointers makes memory management for them explicit and that is a good thing in this case because there is simply no way the FFI could automatically figure out how the optimal memory management strategy for structures passed by value should look like. For example, whether such a structure can be allocated as an atomic block of memory or not is impossible to answer without knowing what the functions producing and consuming instances of the structure actually do. I slightly disagree here. A structure passed or returned by value is just shoved on the stack, maybe in registers if it's a small structure. There's no extra memory management required; merely some extra copying to copy from the Chicken-side foreign-type pointer into the appropriate bit of stack or registers, or back again for returned values. But, indeed, it's easy to do that in C as your distim demonstration shows; return values are only slightly harder as you'll need to allocate a struct and copy the result in, then return that pointer. ABS - -- Alaric Snell-Pym http://www.snell-pym.org.uk/alaric/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk9ONY8ACgkQRgz/WHNxCGpVFQCdFmrrkp6RhMkQQNIaRtElcQUw At8An3tuScsj6vKNCi/CQDVVTeRR1ZHE =foQX -END PGP SIGNATURE- ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] foreign: Why is passing structs as arguments and return-types not supported?
Thanks to both of you for some valuable insight! I didn't realize de-referencing on the c-side would be that simple, nor that structs-by-value would actually be pointers anyway. However, my problem is still not entirely solved. I am trying to interface to the physics engines Box2D and Chipmunk, which are quite big. They both use struct-by-value extensively. Small structs like struct b2Vec2 {float x,y}; are passed around virtually everywhere. When I use `chicken-bind` on my stripped-down version of Box2D.h, it generates foreign-lambda's that return struct-by-value without complaint. When I compile, it fails like the docs say: Error: illegal foreign return type `b2Vec2' Since struct-by-value is so central in both of these libraries, manually writing wrapper-code would take too long. I am unsure of where to go from here, but I suppose my options are: - Modify `foreign` to support struct-by-value - Modify `chicken-bind` to automatically write wrapper-code for struct-by-value - Write a script that re-parses the generated scheme-binding and inserts the wrappers Any thoughts on how to pursue this? Thanks! K. On Wed, Feb 29, 2012 at 3:26 PM, Alaric Snell-Pym ala...@snell-pym.org.ukwrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 02/29/2012 01:29 PM, Thomas Chust wrote: Last but not least, passing structures as pointers makes memory management for them explicit and that is a good thing in this case because there is simply no way the FFI could automatically figure out how the optimal memory management strategy for structures passed by value should look like. For example, whether such a structure can be allocated as an atomic block of memory or not is impossible to answer without knowing what the functions producing and consuming instances of the structure actually do. I slightly disagree here. A structure passed or returned by value is just shoved on the stack, maybe in registers if it's a small structure. There's no extra memory management required; merely some extra copying to copy from the Chicken-side foreign-type pointer into the appropriate bit of stack or registers, or back again for returned values. But, indeed, it's easy to do that in C as your distim demonstration shows; return values are only slightly harder as you'll need to allocate a struct and copy the result in, then return that pointer. ABS - -- Alaric Snell-Pym http://www.snell-pym.org.uk/alaric/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk9ONY8ACgkQRgz/WHNxCGpVFQCdFmrrkp6RhMkQQNIaRtElcQUw At8An3tuScsj6vKNCi/CQDVVTeRR1ZHE =foQX -END PGP SIGNATURE- ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] foreign: Why is passing structs as arguments and return-types not supported?
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 02/29/2012 03:18 PM, Kristian Lein-Mathisen wrote: Since struct-by-value is so central in both of these libraries, manually writing wrapper-code would take too long. I am unsure of where to go from here, but I suppose my options are: - Modify `foreign` to support struct-by-value - Modify `chicken-bind` to automatically write wrapper-code for struct-by-value - Write a script that re-parses the generated scheme-binding and inserts the wrappers Any thoughts on how to pursue this? I would think that the first option is slightly neater, as it would then apply to users of foreign other than via chicken-bind, but it might be easier to do in chicken-bind! The last option looks ugly. ABS - -- Alaric Snell-Pym http://www.snell-pym.org.uk/alaric/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk9OU8wACgkQRgz/WHNxCGrkdQCcDmKaG/yaXUzrIejXupDQ34zX y+MAn2eyLzmMwE+Swah/xbIH1NfH0S4W =gqMq -END PGP SIGNATURE- ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] foreign: Why is passing structs as arguments and return-types not supported?
Kristian Lein-Mathisen kristianl...@gmail.com writes: Any thoughts on how to pursue this? Another option would be to create a module which re-exports all `foreign' syntax wrapped with support for structs-by-value. Then just import your wrapper module instead of `foreign' in the code generated by `chicken-bind'. Moritz ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users