[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