2011-07-21

FFIが動いた!!!

libffiを使っているので、ある意味当たり前なのだが、こんなコードが動いた。
(define kernel32 (open-shared-library "kernel32.dll"))
;; 構造体もサポートしてるぜ!!
(define-c-struct systemtime
  (unsigned-short year)
  (unsigned-short month)
  (unsigned-short day-of-week)
  (unsigned-short day)
  (unsigned-short hour)
  (unsigned-short minute)
  (unsigned-short second)
  (unsigned-short milliseconds))

(let ((proc (c-function kernel32 void GetLocalTime (void*)))
      ;; ughh
      (sys (c-malloc (size-of-c-struct systemtime))))
  (proc sys)
  ;; アクセスの仕方は考えた方がいいかもしれない。ちょっとダサい。
  (print (c-struct-ref sys systemtime 'year)) ;; 2011
  (c-free sys))
ちなみにコールバックも兼ね備えていて(まぁlibffiのおかげだが)、こんなこともできる。
(define lib (open-shared-library "add.so"))
(define array (u8-list->bytevector '(6 5 3 4 1 7 2)))
(let* ([qsort (c-function lib void quicksort (void* size_t size_t callback))]
       [compare (c-callback int (void* void*) 
       (lambda (x y)
         (- (pointer-ref-c-uint8 x 0)
     (pointer-ref-c-uint8 y 0))))])
  (qsort array (bytevector-length array) 1 compare)
  (display array)
  (free-c-callback compare))
add.soなんてのを使ってるのは、cygwin上でのlibcがどれだか分からなかったため。。。
単にqsortの自力実装なんだけど、まぁ動く。
実行結果が、ソートされてないのはmoshもだったので気にしない(でいいのか?)

できればlibffiをバインドしたいんだけど、あんなに複雑なconfigure.acをCMakeLists.txtにできる気がしないので、後回しということにしてしまう。。。

No comments:

Post a Comment