On 2011-12-14, at 5:10 AM, Vok Vojwo wrote:
2011/12/12 Marc Feeley feeley@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