* Re: Passing C pointers through guile @ 2008-07-09 20:09 Kjetil S. Matheussen 2008-07-09 20:43 ` Ludovic Courtès 2008-07-11 13:05 ` Greg Troxel 0 siblings, 2 replies; 13+ messages in thread From: Kjetil S. Matheussen @ 2008-07-09 20:09 UTC (permalink / raw) To: guile-devel Ludovic Court?s: >> I gave it a try. Unfortunately, I was completely unable to create >> the configure file right now, so the patch is against 1.8.5 (sorry >> if this creats trouble against git repository), and >> it's also untested, since I couldn't build configure. > >You have to make sure you are on the `branch_release-1-8', and then >"autoreconf -vfi" should suffice to produce everything. Autoconf 2.61, >Automake 1.10 and Libtool 1.5.26 is all you need. Thanks. It would be nice if that information was in the source too... > > The only thing I'm not too sure about is whether > > the new SCM_I_GSC_T_UINTPTR type in configure.in will actually be > > optional or not. I just copied the checking code for the optional > > SCM_I_GSC_T_UINT64 type though: > > I think this type shouldn't be optional, because there will always be a > pointer-sized integer type (whereas there could be platform without > 64-bit integers). But isn't the only way to make sure that an integer size is big enough to hold a pointer, to use uintptr_t from stdint.h ? It does get a little bit complicated if Guile is compiled on a platform without stdint.h >>> That said, using a Scheme integer to represent a pointer wouldn't be >>> efficient (pointers would likely translate to bignums). >> >> I think cleaner code would usually be more important in this case, >> but at least there will be a choice. > >I'm not sure how much cleaner this is. Usually, you'll want disjoint >Scheme types, which means you'll end up enclosing the pointer-as-bignum >in a structure or SRFI-9 record or similar. This leads to even more >overhead. Conversely, using an opaque field in a Guile struct has the >same effect but with much less overhead. It's cleaner because it requires a magnitude less code. >Another issue is that of memory management. When using >pointers-as-bignums, all the GC will see is a collection of bignums, not >knowing that these are actually pointers to C objects that should not be >GC'd unless the integer is no longer used---as opposed to "no longer >referenced"! This actually makes it mandatory to enclose the integer in >a structure or similar, and then to have a guardian on that structure to >allow the C object's destructor to be called when that structure is no >longer referenced. That's true. But at least my experience is that using guardians is cleaner than smurf's. For example, I think the use of guardians for faust objects in http://snd.cvs.sourceforge.net/snd/cvs-snd/rt-faust.scm is very simple, it's just one line: "(add-finalizer (-> faust get-c-object) cleanup-faust-object)". Also, various types of non-gc pointers are stored in integers in all of the rt-*.scm files in http://snd.cvs.sourceforge.net/snd/cvs-snd/ and many others (xg.c, etc.). It would be horribly idiotic to write smurf's for all of those, or at least a common smurf, when a single integer is enough. >PS: You'll have to assign copyright to the FSF so that your code can be > integrated. We can discuss it off-line if you want. Okay, just tell me what to do. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Passing C pointers through guile 2008-07-09 20:09 Passing C pointers through guile Kjetil S. Matheussen @ 2008-07-09 20:43 ` Ludovic Courtès 2008-07-11 13:05 ` Greg Troxel 1 sibling, 0 replies; 13+ messages in thread From: Ludovic Courtès @ 2008-07-09 20:43 UTC (permalink / raw) To: guile-devel Hey, "Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes: > Ludovic Court?s: >>You have to make sure you are on the `branch_release-1-8', and then >>"autoreconf -vfi" should suffice to produce everything. Autoconf 2.61, >>Automake 1.10 and Libtool 1.5.26 is all you need. > > Thanks. It would be nice if that information was in the source > too... Well, `configure.in' has an `AC_PREREQ' call, 1.10(.1) is the latest Automake, and 1.5.26 is the latest Libtool of the 1.x series, it's easy. :-) >> I think this type shouldn't be optional, because there will always be a >> pointer-sized integer type (whereas there could be platform without >> 64-bit integers). > > But isn't the only way to make sure that an integer size > is big enough to hold a pointer, to use uintptr_t from > stdint.h ? No. `configure' checks the size of a number of (integer) types. The idea here would be to have a check for `void *' (if there isn't one already); then in `numbers.h', you'd add something along the lines of: #if SCM_SIZEOF_VOID_P == 4 #define scm_to_uintptr scm_to_uint32 [...] #elif SCM_SIZEOF_VOID_P == 8 #define scm_to_uintptr scm_to_uint64 [...] #else #error "strange `void *'" #endif IOW, don't rely on <stdint.h> or <inttypes.h>. > That's true. But at least my experience is that using guardians > is cleaner than smurf's. Smurf? Smurf's what? > For example, I think the use of guardians for > faust objects in http://snd.cvs.sourceforge.net/snd/cvs-snd/rt-faust.scm > is very simple, it's just one line: "(add-finalizer (-> faust > get-c-object) cleanup-faust-object)". Yes, guardians are easy to use. > Also, various types of non-gc pointers are stored in integers in > all of the rt-*.scm files in http://snd.cvs.sourceforge.net/snd/cvs-snd/ > and many others (xg.c, etc.). It would be horribly idiotic > to write smurf's for all of those, or at least a common smurf, when a > single integer is enough. Do you mean "SMOB" instead of "smurf"? :-) If so, the deallocation routine that's called from the guardian (which is necessarily written in C) is roughly the same as the one you'd pass to `scm_set_smob_free ()'. Thanks, Ludovic. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Passing C pointers through guile 2008-07-09 20:09 Passing C pointers through guile Kjetil S. Matheussen 2008-07-09 20:43 ` Ludovic Courtès @ 2008-07-11 13:05 ` Greg Troxel 2008-07-11 13:12 ` Kjetil S. Matheussen 1 sibling, 1 reply; 13+ messages in thread From: Greg Troxel @ 2008-07-11 13:05 UTC (permalink / raw) To: Kjetil S. Matheussen; +Cc: guile-devel "Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes: > Also, various types of non-gc pointers are stored in integers in > all of the rt-*.scm files in http://snd.cvs.sourceforge.net/snd/cvs-snd/ > and many others (xg.c, etc.). It would be horribly idiotic > to write smurf's for all of those, or at least a common smurf, when a > single integer is enough. What fraction of these uses are actually correct? Have people run this code on Windows 64 (which is LLP64, but on which long is 32 bits), sparc64, and alpha. I'm always worried when people store pointers in integers - it's IMHO basically a wrong thing to do. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Passing C pointers through guile 2008-07-11 13:05 ` Greg Troxel @ 2008-07-11 13:12 ` Kjetil S. Matheussen 2008-07-11 14:42 ` Ludovic Courtès 0 siblings, 1 reply; 13+ messages in thread From: Kjetil S. Matheussen @ 2008-07-11 13:12 UTC (permalink / raw) To: Greg Troxel; +Cc: guile-devel, Kjetil S. Matheussen On Fri, 11 Jul 2008, Greg Troxel wrote: > "Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes: > >> Also, various types of non-gc pointers are stored in integers in >> all of the rt-*.scm files in http://snd.cvs.sourceforge.net/snd/cvs-snd/ >> and many others (xg.c, etc.). It would be horribly idiotic >> to write smurf's for all of those, or at least a common smurf, when a >> single integer is enough. > > What fraction of these uses are actually correct? Have people run this > code on Windows 64 (which is LLP64, but on which long is 32 bits), > sparc64, and alpha. All of them are correct. The alternative would be messier code. The code in question doesn't run on those platforms anyway, since there's a lot of strict linux stuff. However, I don't the storage of pointers in unsigned longs (which is a perfectly legal thing to do if done correctly), would pose any problem for running it on other hardware. > I'm always worried when people store pointers in > integers - it's IMHO basically a wrong thing to do. > In many situations, like the one above, it's a perfectly fine thing to do, and also the only sane option. Of course, you must know what you are doing. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Passing C pointers through guile 2008-07-11 13:12 ` Kjetil S. Matheussen @ 2008-07-11 14:42 ` Ludovic Courtès 0 siblings, 0 replies; 13+ messages in thread From: Ludovic Courtès @ 2008-07-11 14:42 UTC (permalink / raw) To: guile-devel Hi, "Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes: > The code in question doesn't run on those platforms anyway, > since there's a lot of strict linux stuff. You are certainly aware that GNU/Linux *is* available on sparc64, alpha, etc. > However, I don't the storage of pointers in unsigned longs (which is a > perfectly legal thing to do if done correctly), would pose any problem > for running it on other hardware. Again, it's not "perfectly legal", no matter whether you do it "correctly" (whatever that means) or not: the C standard makes no provision regarding the size of `long' versus the size of pointer types. It happens to work on the mainstream platforms you're using, but it's definitely not portable. And I suppose that's the reason why you want `scm_{to,from}_uintptr ()' in the first place, otherwise you'd just live (dangerously) with `scm_{to,from}_unsigned_long ()'. Thanks, Ludovic. ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <cmu-lmtpd-26382-1215792388-9@mail-imap1.uio.no>]
* Re: Passing C pointers through guile [not found] <cmu-lmtpd-26382-1215792388-9@mail-imap1.uio.no> @ 2008-07-11 17:22 ` Kjetil S. Matheussen 0 siblings, 0 replies; 13+ messages in thread From: Kjetil S. Matheussen @ 2008-07-11 17:22 UTC (permalink / raw) To: guile-devel Ludovic Court?s: > "Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes: > >> The code in question doesn't run on those platforms anyway, >> since there's a lot of strict linux stuff. > > You are certainly aware that GNU/Linux *is* available on sparc64, alpha, > etc. > Well, yes, but he wrote windows 64, sparc64, alpha etc. >> However, I don't the storage of pointers in unsigned longs (which is a >> perfectly legal thing to do if done correctly), would pose any problem >> for running it on other hardware. > > Again, it's not "perfectly legal", no matter whether you do it > "correctly" (whatever that means) or not: the C standard makes no > provision regarding the size of `long' versus the size of pointer types. > It happens to work on the mainstream platforms you're using, but it's > definitely not portable. > > And I suppose that's the reason why you want `scm_{to,from}_uintptr ()' > in the first place, otherwise you'd just live (dangerously) with > `scm_{to,from}_unsigned_long ()'. > Yes, and this is a stupid discussion. We don't really disagree about anything unless anyone thinks I should change all my code using scheme numbers to hold pointers into SMOB's, which would significantly increase the code size which further would increase the chance of bugs. There are, as I have given examples of already, types of pointer where SMOB's are overkill. And just for trying out smaller things, it a lot of work to set up all that SMOB code (again!). I do a lot of interaction between C and scheme, and avoiding SMOBs as much as possible saves me a lot of time. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Passing C pointers through guile @ 2008-07-10 12:49 Kjetil S. Matheussen 2008-07-10 13:01 ` Ludovic Courtès 0 siblings, 1 reply; 13+ messages in thread From: Kjetil S. Matheussen @ 2008-07-10 12:49 UTC (permalink / raw) To: guile-devel Ludovic Court?s: > > Well, `configure.in' has an `AC_PREREQ' call, 1.10(.1) is the latest > Automake, and 1.5.26 is the latest Libtool of the 1.x series, it's > easy. Thanks, I didn't know that. >No. `configure' checks the size of a number of (integer) types. The >idea here would be to have a check for `void *' (if there isn't one >already); then in `numbers.h', you'd add something along the lines of: > > #if SCM_SIZEOF_VOID_P == 4 > #define scm_to_uintptr scm_to_uint32 > [...] > #elif SCM_SIZEOF_VOID_P == 8 > #define scm_to_uintptr scm_to_uint64 > [...] > #else > #error "strange `void *'" > #endif > > IOW, don't rely on <stdint.h> or <inttypes.h>. Good idea. Much better. I'll do that. >> That's true. But at least my experience is that using guardians >> is cleaner than smurf's. > >Smurf? Smurf's what? Oops. :-) I ment SMOB. >If so, the deallocation routine that's called from the guardian (which >is necessarily written in C) is roughly the same as the one you'd pass >to `scm_set_smob_free ()'. Point is that you very often don't need any kind of free functionality. For example, if you create a gui widget, you probably have a callback function which is called if the gui is closed. That callback function can free any allocated memory. Another example from snd is creating ladspa plugins (audio plugins in linux). Handlers from those, plus variuos configuration stuff, is alive througout the whole session and will be automatically freed when the program closes. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Passing C pointers through guile 2008-07-10 12:49 Kjetil S. Matheussen @ 2008-07-10 13:01 ` Ludovic Courtès 0 siblings, 0 replies; 13+ messages in thread From: Ludovic Courtès @ 2008-07-10 13:01 UTC (permalink / raw) To: guile-devel Hi, "Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes: > Point is that you very often don't need any kind of free functionality. > For example, if you create a gui widget, you probably have a callback > function which is called if the gui is closed. That callback > function can free any allocated memory. Another example from snd > is creating ladspa plugins (audio plugins in linux). Handlers > from those, plus variuos configuration stuff, is alive througout > the whole session and will be automatically freed when the program > closes. Sure, but the general case is that a C-implemented object must be explicitly destroyed when it's no longer referenced by Scheme code. Thanks, Ludovic. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Passing C pointers through guile
@ 2008-07-09 19:58 Kjetil S. Matheussen
0 siblings, 0 replies; 13+ messages in thread
From: Kjetil S. Matheussen @ 2008-07-09 19:58 UTC (permalink / raw)
To: guile-devel
Ludovic Courtès:
>> kjetil <at> ttleush ~/guile-1.8.5 $ gcc -Iinclude/ -Llib lib/libguile.a test.c
> > /tmp/ccMcEAxd.o: In function `main':
> > test.c:(.text+0x1b): undefined reference to `scm_from_uintptr'
> > test.c:(.text+0x2c): undefined reference to `scm_to_uintptr'
> > collect2: ld returned 1 exit status
>
> Normally, there's no such thing as `lib/libguile.a'. The thing is under
> `libguile/.libs/libguile.{so,a}'. Alternatively, it might be the case
> that `SCM_HAVE_T_UINTPTR' is not defined.
Normally, yes, but I installed in the same directory as the source. :-)
Anyway, I have no idea why the above didn't work, but it works now.
I haven't changed any of the files since the last time:
kjetil@ttleush ~/guile-1.8.5 $ gcc test.c -Iinclude lib/libguile.a -lgmp -lm -lltdl -lcrypt
lib/libguile.a(posix.o): In function `scm_tmpnam':
posix.c:(.text+0x14b0): warning: the use of `tmpnam' is dangerous, better use `mkstemp'
kjetil@ttleush ~/guile-1.8.5 $ ./a.out
main: 0x804cd54, p: 804cd54
kjetil@ttleush ~/guile-1.8.5 $
^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <cmu-lmtpd-29205-1215446748-1@mail-imap1.uio.no>]
* Re: Passing C pointers through guile [not found] <cmu-lmtpd-29205-1215446748-1@mail-imap1.uio.no> @ 2008-07-09 16:50 ` Kjetil S. Matheussen 2008-07-09 18:32 ` Kjetil S. Matheussen 2008-07-09 19:35 ` Ludovic Courtès 0 siblings, 2 replies; 13+ messages in thread From: Kjetil S. Matheussen @ 2008-07-09 16:50 UTC (permalink / raw) To: guile-devel [-- Attachment #1: Type: TEXT/PLAIN, Size: 1707 bytes --] Ludovic Court?s: > scenes. > > > I agree with Maciek that it would at least be mind-comforting to have > > functions like scm_to_ptr/etc, although not strictly necessary, > > since using integers works just fine. > > `scm_{to,from}_uintptr ()' could be handy (patches welcome!). > I gave it a try. Unfortunately, I was completely unable to create the configure file right now, so the patch is against 1.8.5 (sorry if this creats trouble against git repository), and it's also untested, since I couldn't build configure. However, the patches are trivial, so I think they work anyway. (crossing fingers) The only thing I'm not too sure about is whether the new SCM_I_GSC_T_UINTPTR type in configure.in will actually be optional or not. I just copied the checking code for the optional SCM_I_GSC_T_UINT64 type though: " ### Optional type scm_t_uintptr if test "$scm_stdint_has_uintptr"; then SCM_I_GSC_T_UINTPTR='"uintptr_t"' SCM_I_GSC_NEEDS_STDINT_H=1 elif test "$scm_inttypes_has_uintptr"; then SCM_I_GSC_T_UINTPTR='"uintptr_t"' SCM_I_GSC_NEEDS_INTTYPES_H=1 else AC_MSG_ERROR([Can't find appropriate type for scm_t_uintptr.]) fi AC_SUBST([SCM_I_GSC_T_UINTPTR]) " Patch for configure.in: http://www.notam02.no/~kjetism/configure.in.diff Patch for libguile/Makefile.in, libguile/__scm.h, libguile/gen-scmconfig.c, libguile/gen-scmconfig.h.in and libguile/numbers.c: http://www.notam02.no/~kjetism/libguile.diff The two patches are also attached. > That said, using a Scheme integer to represent a pointer wouldn't be > efficient (pointers would likely translate to bignums). > I think cleaner code would usually be more important in this case, but at least there will be a choice. [-- Attachment #2: Type: TEXT/PLAIN, Size: 4162 bytes --] diff -ur libguile_org/Makefile.in libguile/Makefile.in --- libguile_org/Makefile.in 2008-05-07 20:08:34.000000000 +0200 +++ libguile/Makefile.in 2008-07-09 17:59:52.000000000 +0200 @@ -298,6 +298,7 @@ SCM_I_GSC_T_UINT64 = @SCM_I_GSC_T_UINT64@ SCM_I_GSC_T_UINT8 = @SCM_I_GSC_T_UINT8@ SCM_I_GSC_T_UINTMAX = @SCM_I_GSC_T_UINTMAX@ +SCM_I_GSC_T_UINTPTR = @SCM_I_GSC_T_UINTPTR@ SCM_I_GSC_USE_NULL_THREADS = @SCM_I_GSC_USE_NULL_THREADS@ SCM_I_GSC_USE_PTHREAD_THREADS = @SCM_I_GSC_USE_PTHREAD_THREADS@ SED = @SED@ diff -ur libguile_org/__scm.h libguile/__scm.h --- libguile_org/__scm.h 2008-04-07 23:30:03.000000000 +0200 +++ libguile/__scm.h 2008-07-09 18:27:57.000000000 +0200 @@ -365,6 +365,12 @@ #define SCM_T_INT64_MAX SCM_I_TYPE_MAX(scm_t_int64,SCM_T_UINT64_MAX) #endif +#if SCM_HAVE_T_UINTPTR +#define SCM_T_UINTPTR_MAX SCM_I_UTYPE_MAX(scm_t_uintptr) +#define SCM_T_UINTPTR_MIN SCM_I_TYPE_MIN(scm_t_uintptr,SCM_T_UINTPTR_MAX) +#define SCM_T_UINTPTR_MAX SCM_I_TYPE_MAX(scm_t_uintptr,SCM_T_UINTPTR_MAX) +#endif + #if SCM_SIZEOF_LONG_LONG #define SCM_I_ULLONG_MAX SCM_I_UTYPE_MAX(unsigned long long) #define SCM_I_LLONG_MIN SCM_I_TYPE_MIN(long long,SCM_I_ULLONG_MAX) diff -ur libguile_org/gen-scmconfig.c libguile/gen-scmconfig.c --- libguile_org/gen-scmconfig.c 2008-04-24 19:35:57.000000000 +0200 +++ libguile/gen-scmconfig.c 2008-07-09 18:24:22.000000000 +0200 @@ -339,6 +339,19 @@ pf ("#define SCM_HAVE_T_UINT64 0 /* 0 or 1 */\n"); pf ("\n"); + pf ("/* unsigned integer large enough to hold pointer -- if available SCM_HAVE_T_UINTPTR will\n" + " be 1 and scm_t_uintptr will be a suitable type, otherwise\n" + " SCM_HAVE_T_UINTPTR will be 0. */\n"); + if (SCM_I_GSC_T_UINTPTR) + { + pf ("#define SCM_HAVE_T_UINTPTR 1 /* 0 or 1 */\n"); + pf ("typedef %s scm_t_intptr;\n", SCM_I_GSC_T_UINTPTR); + } + else + pf ("#define SCM_HAVE_T_UINTPTR 0 /* 0 or 1 */\n"); + + + pf ("\n"); pf ("/* scm_t_ptrdiff_t and size, always defined -- defined to long if\n" " platform doesn't have ptrdiff_t. */\n"); pf ("typedef %s scm_t_ptrdiff;\n", SCM_I_GSC_T_PTRDIFF); @@ -353,6 +366,7 @@ pf ("/* Size of uintptr_t or 0 if not available */\n"); pf ("#define SCM_SIZEOF_UINTPTR_T %d\n", SIZEOF_UINTPTR_T); + pf ("\n"); pf ("/* same as POSIX \"struct timespec\" -- always defined */\n"); #ifdef HAVE_STRUCT_TIMESPEC diff -ur libguile_org/gen-scmconfig.h.in libguile/gen-scmconfig.h.in --- libguile_org/gen-scmconfig.h.in 2008-04-07 23:30:03.000000000 +0200 +++ libguile/gen-scmconfig.h.in 2008-07-09 17:59:00.000000000 +0200 @@ -25,6 +25,7 @@ #define SCM_I_GSC_T_UINT64 @SCM_I_GSC_T_UINT64@ #define SCM_I_GSC_T_INTMAX @SCM_I_GSC_T_INTMAX@ #define SCM_I_GSC_T_UINTMAX @SCM_I_GSC_T_UINTMAX@ +#define SCM_I_GSC_T_UINTPTR @SCM_I_GSC_T_UINTPTR@ #define SCM_I_GSC_T_PTRDIFF @SCM_I_GSC_T_PTRDIFF@ #define SCM_I_GSC_USE_PTHREAD_THREADS @SCM_I_GSC_USE_PTHREAD_THREADS@ #define SCM_I_GSC_USE_NULL_THREADS @SCM_I_GSC_USE_NULL_THREADS@ diff -ur libguile_org/numbers.c libguile/numbers.c --- libguile_org/numbers.c 2008-05-07 17:29:55.000000000 +0200 +++ libguile/numbers.c 2008-07-09 18:25:29.000000000 +0200 @@ -5863,6 +5863,19 @@ #endif + +#if SCM_HAVE_T_UINTPTR + +#define TYPE scm_t_uintptr +#define TYPE_MIN 0 +#define TYPE_MAX SCM_T_UINTPTR_MAX +#define SIZEOF_TYPE 8 +#define SCM_TO_TYPE_PROTO(arg) scm_to_uintptr (arg) +#define SCM_FROM_TYPE_PROTO(arg) scm_from_uintptr (arg) +#include "libguile/conv-uinteger.i.c" + +#endif + void scm_to_mpz (SCM val, mpz_t rop) { diff -ur libguile_org/numbers.h libguile/numbers.h --- libguile_org/numbers.h 2008-04-07 23:30:03.000000000 +0200 +++ libguile/numbers.h 2008-07-09 18:31:06.000000000 +0200 @@ -331,6 +331,13 @@ #endif +#if SCM_HAVE_T_UINTPTR + +SCM_API scm_t_uintptr scm_to_uintptr (SCM x); +SCM_API SCM scm_from_uintptr (scm_t_uintptr x); + +#endif + SCM_API void scm_to_mpz (SCM x, mpz_t rop); SCM_API SCM scm_from_mpz (mpz_t rop); [-- Attachment #3: Type: TEXT/PLAIN, Size: 2069 bytes --] --- configure.in.org 2008-07-09 18:32:53.000000000 +0200 +++ configure.in 2008-07-09 18:46:38.000000000 +0200 @@ -352,6 +352,7 @@ AC_CHECK_TYPE([uint32_t],[scm_stdint_has_uint32=1],,[#include <stdint.h>]) AC_CHECK_TYPE([int64_t],[scm_stdint_has_int64=1],,[#include <stdint.h>]) AC_CHECK_TYPE([uint64_t],[scm_stdint_has_uint64=1],,[#include <stdint.h>]) + AC_CHECK_TYPE([uintptr_t],[scm_stdint_has_uintptr=1],,[#include <stdint.h>]) AC_CHECK_TYPE([intmax_t],[scm_stdint_has_intmax=1],,[#include <stdint.h>]) AC_CHECK_TYPE([uintmax_t],[scm_stdint_has_uintmax=1],,[#include <stdint.h>]) fi @@ -367,6 +368,7 @@ unset ac_cv_type_uint32_t unset ac_cv_type_int64_t unset ac_cv_type_uint64_t +unset ac_cv_type_uintptr_t unset ac_cv_type_intmax_t unset ac_cv_type_uintmax_t @@ -380,6 +382,7 @@ AC_CHECK_TYPE([uint32_t],[scm_inttypes_has_uint32=1],,[#include <inttypes.h>]) AC_CHECK_TYPE([int64_t],[scm_inttypes_has_int64=1],,[#include <inttypes.h>]) AC_CHECK_TYPE([uint64_t],[scm_inttypes_has_uint64=1],,[#include <inttypes.h>]) + AC_CHECK_TYPE([uintptr_t],[scm_inttypes_has_uintptr=1],,[#include <inttypes.h>]) AC_CHECK_TYPE([intmax_t],[scm_inttypes_has_intmax=1],,[#include <inttypes.h>]) AC_CHECK_TYPE([uintmax_t],[scm_inttypes_has_uintmax=1],,[#include <inttypes.h>]) fi @@ -532,6 +535,20 @@ fi AC_SUBST([SCM_I_GSC_T_UINT64]) + +### Optional type scm_t_uintptr +if test "$scm_stdint_has_uintptr"; then + SCM_I_GSC_T_UINTPTR='"uintptr_t"' + SCM_I_GSC_NEEDS_STDINT_H=1 +elif test "$scm_inttypes_has_uintptr"; then + SCM_I_GSC_T_UINTPTR='"uintptr_t"' + SCM_I_GSC_NEEDS_INTTYPES_H=1 +else + AC_MSG_ERROR([Can't find appropriate type for scm_t_uintptr.]) +fi +AC_SUBST([SCM_I_GSC_T_UINTPTR]) + + ### Required type scm_t_intmax ### ### We try 'intmax_t', '__int64', 'long long' in this order. When @@ -553,6 +570,7 @@ fi AC_SUBST([SCM_I_GSC_T_INTMAX]) + ### Required type scm_t_uintmax ### ### We try 'uintmax_t', 'unsigned __int64', 'unsigned long long' in ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Passing C pointers through guile 2008-07-09 16:50 ` Kjetil S. Matheussen @ 2008-07-09 18:32 ` Kjetil S. Matheussen 2008-07-09 19:37 ` Ludovic Courtès 2008-07-09 19:35 ` Ludovic Courtès 1 sibling, 1 reply; 13+ messages in thread From: Kjetil S. Matheussen @ 2008-07-09 18:32 UTC (permalink / raw) To: Kjetil S. Matheussen; +Cc: guile-devel On Wed, 9 Jul 2008, Kjetil S. Matheussen wrote: > > Ludovic Court?s: > > scenes. > > > > > I agree with Maciek that it would at least be mind-comforting to have > > > functions like scm_to_ptr/etc, although not strictly necessary, > > > since using integers works just fine. > > > > `scm_{to,from}_uintptr ()' could be handy (patches welcome!). > > > > I gave it a try. Unfortunately, I was completely unable to create > the configure file right now, so the patch is against 1.8.5 (sorry > if this creats trouble against git repository), and > it's also untested, since I couldn't build configure. However, > the patches are trivial, so I think they work anyway. (crossing fingers) > Stupid me. I could of course compile 1.8.5 since I have autoconf 1.60. And by doing that, I found three trivial typos. New version of http://www.notam02.no/~kjetism/libguile.diff is uploaded. However, I can't get it to work...: " kjetil@ttleush ~/guile-1.8.5 $ CFLAGS=-O3 ./configure --prefix=/home/kjetil/guile-1.8.5 --without-threads ... kjetil@ttleush ~/guile-1.8.5 $ make && make install ... kjetil@ttleush ~/guile-1.8.5 $ more test.c #include <libguile.h> #include <libguile/numbers.h> int main(){ SCM t=scm_from_uintptr((scm_t_uintptr)&main); scm_t_uintptr m=scm_to_uintptr(t); printf("main: %p, p: %x\n",&main,m); return 0; } kjetil@ttleush ~/guile-1.8.5 $ gcc -Iinclude/ -Llib lib/libguile.a test.c /tmp/ccMcEAxd.o: In function `main': test.c:(.text+0x1b): undefined reference to `scm_from_uintptr' test.c:(.text+0x2c): undefined reference to `scm_to_uintptr' collect2: ld returned 1 exit status kjetil@ttleush ~/guile-1.8.5 $ " Any idea why? ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Passing C pointers through guile 2008-07-09 18:32 ` Kjetil S. Matheussen @ 2008-07-09 19:37 ` Ludovic Courtès 0 siblings, 0 replies; 13+ messages in thread From: Ludovic Courtès @ 2008-07-09 19:37 UTC (permalink / raw) To: guile-devel Hi, "Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes: > kjetil@ttleush ~/guile-1.8.5 $ gcc -Iinclude/ -Llib lib/libguile.a test.c > /tmp/ccMcEAxd.o: In function `main': > test.c:(.text+0x1b): undefined reference to `scm_from_uintptr' > test.c:(.text+0x2c): undefined reference to `scm_to_uintptr' > collect2: ld returned 1 exit status Normally, there's no such thing as `lib/libguile.a'. The thing is under `libguile/.libs/libguile.{so,a}'. Alternatively, it might be the case that `SCM_HAVE_T_UINTPTR' is not defined. Thanks, Ludovic. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Passing C pointers through guile 2008-07-09 16:50 ` Kjetil S. Matheussen 2008-07-09 18:32 ` Kjetil S. Matheussen @ 2008-07-09 19:35 ` Ludovic Courtès 1 sibling, 0 replies; 13+ messages in thread From: Ludovic Courtès @ 2008-07-09 19:35 UTC (permalink / raw) To: guile-devel Hi, "Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes: > I gave it a try. Unfortunately, I was completely unable to create > the configure file right now, so the patch is against 1.8.5 (sorry > if this creats trouble against git repository), and > it's also untested, since I couldn't build configure. You have to make sure you are on the `branch_release-1-8', and then "autoreconf -vfi" should suffice to produce everything. Autoconf 2.61, Automake 1.10 and Libtool 1.5.26 is all you need. > The only thing I'm not too sure about is whether > the new SCM_I_GSC_T_UINTPTR type in configure.in will actually be > optional or not. I just copied the checking code for the optional > SCM_I_GSC_T_UINT64 type though: I think this type shouldn't be optional, because there will always be a pointer-sized integer type (whereas there could be platform without 64-bit integers). >> That said, using a Scheme integer to represent a pointer wouldn't be >> efficient (pointers would likely translate to bignums). > > I think cleaner code would usually be more important in this case, > but at least there will be a choice. I'm not sure how much cleaner this is. Usually, you'll want disjoint Scheme types, which means you'll end up enclosing the pointer-as-bignum in a structure or SRFI-9 record or similar. This leads to even more overhead. Conversely, using an opaque field in a Guile struct has the same effect but with much less overhead. Another issue is that of memory management. When using pointers-as-bignums, all the GC will see is a collection of bignums, not knowing that these are actually pointers to C objects that should not be GC'd unless the integer is no longer used---as opposed to "no longer referenced"! This actually makes it mandatory to enclose the integer in a structure or similar, and then to have a guardian on that structure to allow the C object's destructor to be called when that structure is no longer referenced. (Note that it could be a valid approach in some compiler environments. It just doesn't fit well with Guile's design.) Anyway, it can't hurt to have the choice. :-) Thanks, Ludovic. PS: You'll have to assign copyright to the FSF so that your code can be integrated. We can discuss it off-line if you want. ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2008-07-11 17:22 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-07-09 20:09 Passing C pointers through guile Kjetil S. Matheussen 2008-07-09 20:43 ` Ludovic Courtès 2008-07-11 13:05 ` Greg Troxel 2008-07-11 13:12 ` Kjetil S. Matheussen 2008-07-11 14:42 ` Ludovic Courtès [not found] <cmu-lmtpd-26382-1215792388-9@mail-imap1.uio.no> 2008-07-11 17:22 ` Kjetil S. Matheussen -- strict thread matches above, loose matches on Subject: below -- 2008-07-10 12:49 Kjetil S. Matheussen 2008-07-10 13:01 ` Ludovic Courtès 2008-07-09 19:58 Kjetil S. Matheussen [not found] <cmu-lmtpd-29205-1215446748-1@mail-imap1.uio.no> 2008-07-09 16:50 ` Kjetil S. Matheussen 2008-07-09 18:32 ` Kjetil S. Matheussen 2008-07-09 19:37 ` Ludovic Courtès 2008-07-09 19:35 ` Ludovic Courtès
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).