[gambit-list] How to pass a Scheme string to a const char*?
Marc Feeley
feeley at iro.umontreal.ca
Wed Dec 14 08:11:49 EST 2011
On 2011-12-14, at 5:10 AM, Vok Vojwo wrote:
> 2011/12/12 Marc Feeley <feeley at iro.umontreal.ca>:
>> I finally understand the problem you were explaining. It is that openlog stores a pointer to the "ident" string that will be used in subsequent calls to syslog. It does not take a copy of the string. This means the C string which was converted from Scheme for the first argument of openlog must remain live after the call to openlog returns.
>
> Exactly.
>
>> This can be accomplished by incrementing the reference count on the C string when openlog is called, and decrementing the reference count on the closelog call.
>
> Thank you for explaining this.
>
>> (c-declare "static char *temp = NULL;")
>>
>> (define openlog
>> (c-lambda
>> (char-string int int)
>> void
>> "if (temp != NULL) ___EXT(___release_string)(temp);
>> temp = ___arg1;
>> ___EXT(___addref_string)(___arg1);
>> openlog(___arg1,___arg2,___arg3);"))
>>
>> (define closelog
>> (c-lambda
>> ()
>> void
>> "if (temp != NULL) ___EXT(___release_string)(temp);
>> closelog();"))
>
> But how about the GC moving the string around? As far as I understood
> it is possible that the string in arg1 moves somewhere else. After
> that temp would not point to the string any more.
When a Scheme string is "converted" to a C string by the C-interface, it is a newly allocated object on the C heap. In other words, the object that C is receiving is unrelated to the Scheme object managed by the Gambit garbage-collector. The C string will *not* be moved around, but it does have a reference count which allows more control over the reclaiming of that string from the C side.
Marc
More information about the Gambit-list
mailing list