Hi David, David Pirotte <da...@altosw.be> writes:
> Hello, > > guile 2.2.4.1-cdb19 > > ,use (system foreign) > > ;; this fails > > scheme@(guile-user)> (make-c-struct (list '* '*) (list (string->pointer > "hello ") (string->pointer "there!"))) > $16 = #<pointer 0x55a3d54d54d0> > scheme@(guile-user)> (parse-c-struct $16 (list '* '*)) > $17 = (#<pointer 0x55a3d5d12170> #<pointer 0x55a3d5d0a640>) > scheme@(guile-user)> (map pointer->string $17) > $18 = ("?g?գU" "`!?գU") The Guile manual states: -- Scheme Procedure: string->pointer string [encoding] Return a foreign pointer to a nul-terminated copy of STRING in the given ENCODING, defaulting to the current locale encoding. The C string is freed when the returned foreign pointer becomes unreachable. Note the last sentence. When the returned foreign pointer (object) becomes unreachable, the C string is freed. The problem here is that you're not keeping a reference to those foreign pointer objects. If you look at the code in foreign.c, specifically 'scm_string_to_pointer' and 'scm_from_pointer', you'll see that the C pointer is wrapped within a heap-allocated foreign pointer object, and a finalizer is being set on that heap object. 'make-c-struct' copies the C pointers from those foreign pointer objects, but not not keep a reference to the objects themselves. In a later message, you wrote: > Following your explanation and example, I tried this and thought it would > work then, > but it also failed: > > GNU Guile 2.2.4.1-cdb19 > Copyright (C) 1995-2017 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)> ,use (system foreign) > scheme@(guile-user)> (define str-1 "Hello") > scheme@(guile-user)> (define str-2 "there!") > scheme@(guile-user)> (make-c-struct (list '* '*) (list (string->pointer > str-1) (string->pointer str-2))) > $2 = #<pointer 0x55ae02e57830> > scheme@(guile-user)> (parse-c-struct $2 (list '* '*)) > $3 = (#<pointer 0x55ae02f9e3c0> #<pointer 0x55ae02f8b050>) > scheme@(guile-user)> (map pointer->string $3) > $4 = ("" "`\v?\x02?U") Here are you specifically saving a reference to the Scheme string objects, but that's not what's needed. What's needed is to hold references to the foreign pointer objects returned by 'string->pointer' for as long as the C strings are needed. Regards, Mark