[racket] ffi->SendMessageTimeoutW
On Fri, 18 Jan 2013, heraklea at 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 1600 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.racket-lang.org/users/archive/attachments/20130118/abdc224b/attachment.p7s>