> 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