SapphireDensetsu / ypsilon

Automatically exported from code.google.com/p/ypsilon
Other
0 stars 0 forks source link

Question/Request #31

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Nice work, of course I start using it...

I'm trying to build some libraries for Ypsilon, calling existing C
functions. Is there any way to transfer C-strings to Ypsilon and vice
verse, retrive an C-string from Ypsilon?

 /anders

Original issue reported on code.google.com by anders.n...@comhem.se on 16 Jul 2008 at 5:51

GoogleCodeExporter commented 8 years ago
Soory - just found out that you can get a C-string from Ypsilon, sorry. But I 
cannot
still find how to return a C-string to Ypsilon

/anders

Original comment by anders.n...@comhem.se on 16 Jul 2008 at 6:38

GoogleCodeExporter commented 8 years ago
Thank you for your message.

There is no documentation for FFI yet. Sorry for your inconvenience.
I wrote an example to get c-string as follows.
Please check it and please let me know if you have any question. :)

;;-------------

;; Because FFI is now under development and there is no API
;; available for c-string at this moment, we need helper
;; function to get c-string from bytevector.

(define ->string
  (lambda (buf)
    (let ((s (bytevector->string buf (make-transcoder (utf-8-codec)))))
      (let loop ((i 0))
        (if (char=? (string-ref s i) #\nul)
            (substring s 0 i)
            (loop (+ i 1)))))))

;;

(import (ffi))

;; this example use linux standard C library
(define libStdC (load-shared-object "libc.so.6"))

;; C prototype: int gethostname(char *name, size_t len);
;; use argument type 'byte*' to receive c-string
(define gethostname (c-function libStdC "Standard C Library" int gethostname 
(byte*
int)))

;; bytevector for buffer
(define bufsize 32)
(define buf (make-bytevector bufsize))

;; argument type 'byte*' expect bytevector
(gethostname buf bufsize) ;=> 0
(->string buf) ;=> "ubuntu-core2"

;; C prototype: int snprintf(char *s, size_t n, const char *format, ...);
;; use argument type 'char*' to pass c-string
;; use argument type 'byte*' to receive c-string
;; use argument type 'int' for size_t (32bit mode)
;; variadic arguments definition not supported, we need separate FFI definition
;; for different argument type and/or count.
(define snprintf1d (c-function libStdC "Standard C Library" int snprintf (byte* 
int
char* double)))
(define snprintf2s (c-function libStdC "Standard C Library" int snprintf (byte* 
int
char* char* char*)))

(snprintf1d buf bufsize "%10.02f" 1.2546456) ;=> 10
(->string buf) ;=> "      1.25"
(snprintf2s buf bufsize "%10s %10s" "Planet:" "Jupiter") ;=> 21
(->string buf) ;=> "   Planet:    Jupiter"

;;-------------

Original comment by y.fujita...@gmail.com on 17 Jul 2008 at 3:13

GoogleCodeExporter commented 8 years ago
OK,

I'll give it a try during the weekend. 
Thanks for your quick reply;-)
/anders

Original comment by anders.n...@comhem.se on 17 Jul 2008 at 7:49

GoogleCodeExporter commented 8 years ago
Hi again,

the solution works for my needs so far. 
You can close this item. 
thanks / anders

Original comment by anders.n...@comhem.se on 19 Jul 2008 at 5:26

GoogleCodeExporter commented 8 years ago
I'm happy to hear that :)
Thank you!

Original comment by y.fujita...@gmail.com on 20 Jul 2008 at 7:31