From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Amirouche Boubekki Newsgroups: gmane.lisp.guile.user Subject: Re: Bytestructures, FFI Date: Tue, 31 May 2016 22:13:32 +0200 Message-ID: References: <87oa7mauvd.fsf@T420.taylan> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1464725662 27640 80.91.229.3 (31 May 2016 20:14:22 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 31 May 2016 20:14:22 +0000 (UTC) Cc: guile-user@gnu.org, guile-user To: taylanbayirli@gmail.com Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Tue May 31 22:14:11 2016 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1b7q3H-0003f0-1d for guile-user@m.gmane.org; Tue, 31 May 2016 22:14:11 +0200 Original-Received: from localhost ([::1]:38235 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b7q3F-0001NG-Vc for guile-user@m.gmane.org; Tue, 31 May 2016 16:14:09 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:42138) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b7q2t-0001N0-H6 for guile-user@gnu.org; Tue, 31 May 2016 16:13:48 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b7q2r-0008BK-3Y for guile-user@gnu.org; Tue, 31 May 2016 16:13:46 -0400 Original-Received: from relay3-d.mail.gandi.net ([2001:4b98:c:538::195]:53199) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b7q2j-00089E-3q; Tue, 31 May 2016 16:13:37 -0400 Original-Received: from mfilter25-d.gandi.net (mfilter25-d.gandi.net [217.70.178.153]) by relay3-d.mail.gandi.net (Postfix) with ESMTP id 3D216A80C6; Tue, 31 May 2016 22:13:34 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter25-d.gandi.net Original-Received: from relay3-d.mail.gandi.net ([IPv6:::ffff:217.70.183.195]) by mfilter25-d.gandi.net (mfilter25-d.gandi.net [::ffff:10.0.15.180]) (amavisd-new, port 10024) with ESMTP id uurNJJvsRd3F; Tue, 31 May 2016 22:13:32 +0200 (CEST) X-Originating-IP: 10.58.1.144 Original-Received: from webmail.gandi.net (webmail4-d.mgt.gandi.net [10.58.1.144]) (Authenticated sender: amirouche@hypermove.net) by relay3-d.mail.gandi.net (Postfix) with ESMTPA id 7501DA80D2; Tue, 31 May 2016 22:13:32 +0200 (CEST) In-Reply-To: <87oa7mauvd.fsf@T420.taylan> X-Sender: amirouche@hypermove.net User-Agent: Roundcube Webmail/1.1.2 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2001:4b98:c:538::195 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Original-Sender: "guile-user" Xref: news.gmane.org gmane.lisp.guile.user:12587 Archived-At: On 2016-05-31 21:29, taylanbayirli@gmail.com wrote: > Hi there, > > I had announced this project a while ago, here: > > https://lists.gnu.org/archive/html/guile-user/2015-08/msg00034.html > > I just added support for converting a bytestructure descriptor into a > type descriptor as per Guile's FFI module. > > E.g. the uint8 descriptor in (bytestructures guile numeric) converts to > the value of the uint8 variable in the (system foreign) module, and a > struct descriptor such as (bs:struct `((x ,uint8) (y ,uint16))) > converts > to what one would get from evaluating (list uint8 uint16) after > importing (system foreign). (Such lists are accepted by Guile's FFI to > denote structs; it's yet undocumented in the manual.) > > For convenience, a bs:pointer->proc procedure is offered, that wraps > pointer->procedure and adds bytestructure related functionality. > Here's > a minimal example of how to use it: > > > --- start transcript --- > > taylan@T420:~/src/scheme/bytestructures$ cat test.c > typedef struct { > struct { > int x; > float y; > } s; > int z; > float t[3]; > } foo_t; > > foo_t testfunc(foo_t arg) > { > ++arg.s.x; > ++arg.s.y; > ++arg.z; > ++arg.t[0]; > ++arg.t[1]; > ++arg.t[2]; > return arg; > } > taylan@T420:~/src/scheme/bytestructures$ gcc -shared -o libtest.so > test.c > taylan@T420:~/src/scheme/bytestructures$ sudo mv libtest.so /usr/lib/ > taylan@T420:~/src/scheme/bytestructures$ guile > GNU Guile 2.0.11 > Copyright (C) 1995-2014 Free Software Foundation, Inc. > > Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'. > This program is free software, and you are welcome to redistribute it > under certain conditions; type `,show c' for details. > > Enter `,help' for help. > scheme@(guile-user)> (import (bytestructures guile)) > scheme@(guile-user)> (import (bytestructures guile ffi)) > scheme@(guile-user)> (define foo_t (bs:struct `((s ,(bs:struct `((x > ,int) > (y > ,float32)))) > (z ,int) > (t ,(bs:vector 3 > float32))))) IMO This is a better example: scheme@(guile-user)> (define contact_t (bs:struct `((address ,(bs:struct `((street_id ,int) (number ,int)))) (age ,int)))) Or something > scheme@(guile-user)> (define foo (bytestructure address_t '((address > ((street 42) > (number > 12345))) > (age 66))) > scheme@(guile-user)> (bytestructure-ref address 'address 'street) > $1 = 42 > scheme@(guile-user)> (bytestructure-ref address 'age) > $2 = 66 > scheme@(guile-user)> (define testfunc > (bs:pointer->proc > foo_t ;return value type > (dynamic-func "testfunc" (dynamic-link > "libtest")) > (list foo_t))) ;list of argument types Why don't you use dynamic-link* signature like described in [1]: ((dynamic-link* [library-name]) return-type function-name . arguments) [1] http://www.hyperdev.fr/notes/gnu-guile-ffi.html > scheme@(guile-user)> (define foo2 (testfunc foo)) isn't foo2 `equal?' to foo? > > Neat, isn't it? > Awesome! > > If test.c instead contained: > > void testfunc(foo_t *arg) > { > ++arg->s.x; > ++arg->s.y; > ++arg->z; > ++arg->t[0]; > ++arg->t[1]; > ++arg->t[2]; > } > > (i.e. testfunc now takes a struct pointer and modifies it in-place) > > then we could create our procedure like: > > scheme@(guile-user)> (import (prefix (system foreign) ffi:)) > scheme@(guile-user)> (define testfunc > (bs:pointer->proc > ffi:void > (dynamic-func "testfunc" (dynamic-link > "libtest")) > (list '*))) > > and things would work like this: > > scheme@(guile-user)> (testfunc foo) > scheme@(guile-user)> (bytestructure-ref foo 's 'x) > $3 = 2 > scheme@(guile-user)> (bytestructure-ref foo 't 1) > $4 = 2.0 > > Magic! > > > Note that while bytestructures supports unions and bit-fields, libffi > and therefore (system foreign) does not, so the above won't work yet > for > types in which unions or bitfields are involved. Unions can possibly > be > supported with a little hack, which I'll look into later. > > I have not yet made the semantics of bs:pointer->proc concrete, and > it's > yet undocumented. Feel free to ask me questions here or on Freenode > under the nick 'taylan'. Comments are welcome too! > > Taylan -- Amirouche ~ amz3 ~ http://www.hyperdev.fr