> Thanks for the responses. I tried what I could, but it still doesn't work.
> I wrote some code to test if I can open and close a file. The C code works
> but the Chicken code doesn't.
>
> (import (chicken foreign))
>
> (foreign-declare "#include <stdio.h>")
> (foreign-declare "#include <wchar.h>")
>
> (define chicken_wfopen
> (foreign-lambda (c-pointer "FILE") "_wfopen" (c-pointer "wchar_t")
> (c-pointer "wchar_t")))
> (define chicken_fclose
> (foreign-lambda int "fclose" (c-pointer "FILE")))
>
> (let ([file-handle (chicken_wfopen "c:\\temp\\íűőúöüóéá.txt" "r")])
> (print "File has been opened at: " (number->string file-handle))
> (print "Closing file.")
> (chicken_fclose file-handle))
>
> The Chicken code fails with the error message: Error: unbound variable:
> It doesn't say the name of the variable, and it returns the error code 70.
> Note that in C the string needs to be prefixed with an L to make it wide
> character. In Chicken I don't know how to do that.
> Does anybody have a clue which variable is unbound?
Ugh. Sorry, I don't know what variable is meant here. I also gave wrong
information: _wfopen returns a FILE* (as you correctly implement above).
The returned pointer will not be a number, though.
Anyway: the strings you pass are Scheme strings, passes as char *
to the FFI code, this is wrong, as you want UTF-16 Windows strings
(wchar_t *) here. The proper way would be (I think) to do
;; warning: totally untested
(define wfopen
(foreign-lambda* bool ((c-string str) (c-string mode) (scheme-object port))
"int sz1 = 4 * (strlen(str) + 1), sz2 = 4 * (strlen(mode) + 1);
wchar_t *buf1 = malloc(sz1), buf2 = malloc(sz2);
FILE *fp;
MultiByteToWideChar(CP_UTF8, 0, str, -1, buf1, sz1);
MultiByteToWideChar(CP_UTF8, 0, mode, -1, buf2, sz2);
fp = _wfopen(buf1, buf2);
free(buf1); free(buf2);
if(fp == NULL) return(0);
C_set_block_item(port, 0, (C_word)fp);
return(1);"))
(define (fopen-utf16 fname mode input?)
(let ((p (##sys#make-port (if input? 1 2) ##sys#stream-port-class name 'stream)))
(if (wfopen fname mode)
p
(error "error opening file" fname mode))))
the ##sys#make-port thing above creates a proper port to be used in Scheme,
the input? flag is unfortunately needed to distinguish between input and output
ports. Sorry if all this is a bit confusing.
felix
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.