簡體   English   中英

Racket / C FFI中的可變arity函數

[英]Variable arity functions in Racket/C FFI

使用Racket的FFI聲明函數非常簡單,只需使用_fundefine-ffi-definer _fun (可以在PRL博客上找到教程)例如,我可以為atoi進行綁定:

#lang racket
(require ffi/unsafe
         ffi/unsafe/define)
(define-ffi-definer define-libc #f)
(define-libc atoi (_fun _string -> _int))

現在我可以用球拍字符串調用atoi了:

> (atoi "5")
5

現在的問題是,如何使用變量arity調用C函數,例如printf ,其簽名是:

int printf(const char *format, ...);

我猜(由於鏈接是動態發生的),Racket代碼的末尾應該有一個“ rest”參數,該參數為其余參數采用一個數組(指針),即為null終止或(更有可能) ,由另一個論點表示。 但是,我想不出任何好的方法來測試這一點。

那么,如何使用Racket-C FFI處理可變arity函數?

看一下這個解決方案c-printf

(provide c-printf)

(define interfaces (make-hash))

(define (c-printf fmt . args)
  (define itypes
    (cons _string
          (map (lambda (x)
                 (cond [(and (integer? x) (exact? x)) _int]
                       [(and (number? x) (real? x))   _double*]
                       [(string? x)  _string]
                       [(bytes? x)   _bytes]
                       [(symbol? x)  _symbol]
                       [else (error 'c-printf
                                    "don't know how to deal with ~e" x)]))
               args)))
  (let ([printf (hash-ref interfaces itypes
                  (lambda ()
                    ;; Note: throws away the return value of printf
                    (let ([i (get-ffi-obj "printf" #f
                                          (_cprocedure itypes _void))])
                      (hash-set! interfaces itypes i)
                      i)))])
    (apply printf fmt args)))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM