On Fri, 18 Jan 2013, herak...@gmx.de wrote:
[...] (define ENV (cast "Environment" _string/utf-16 _intptr)) [...] But in Racket when I call the function:(define-values ( r4 res4) (SendMessageTimeoutW HWND_BROADCAST WM_SETTINGCHANGE 0 ENV SMTO_ABORTIFHUNG 5000)) I get r4= 1 and res4=0 But (GetLastError) gives 3 and this means ERROR_PATH_NOT_FOUND. Which path is here mentioned? Is the ffi define correct, especially the way I define ENV gives me a headache? [...]
Hello,the C pointer to string data allocated by Racket's FFI when _string/utf-16 processes its input is valid only temporarily until the next time the garbage collector runs. When you cast it to an _intptr and store the result you effectively get some random integer that once corresponded to an address in the Racket heap but there is no guarantee about its meaning whenever you actually want to use it ;-)
You could instead allocate an immobile buffer for the string in UTF-16 encoding, keep it in a module variable to protect it from garbage collection while the pointer is alive and cast the address of the buffer into an _intptr for use as an argument to SendMessageTimeoutW:
(define-values (*ENV ENV) (let* ([data (call-with-output-bytes (lambda (out) (let ([out (reencode-output-port out (string-append "UTF-16" (if (system-big-endian?) "BE" "LE")))]) (display "Environment\u0000" out) (close-output-port out))))] [cdata (malloc 'atomic-interior (bytes-length data))]) (memmove cdata data (bytes-length data)) (values cdata (cast cdata _pointer _intptr))))If you replace 'atomic-interior by 'raw you don't even have to keep the pointer *ENV around since the memory will never be garbage collected. However, you would then need to (free (cast _intptr _pointer ENV)) the memory explicitly at some point when ENV is no longer used.
And yes, this code looks clumsy. I really miss functions like string->bytes/utf-8 for arbitrary encodings, too ;-)
Ciao, Thomas -- When C++ is your hammer, every problem looks like your thumb.
smime.p7s
Description: S/MIME Cryptographic Signature
____________________ Racket Users list: http://lists.racket-lang.org/users