首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态创建球拍中的FFI方法

动态创建球拍中的FFI方法
EN

Stack Overflow用户
提问于 2016-06-11 14:43:36
回答 2查看 1.1K关注 0票数 1

我正在玩的想法,加载С/锈蚀/等功能通过FFI在球拍。我希望将函数名列表指定为字符串,然后通过某个助手函数加载它们。主要问题是从字符串创建标识符/单词。例如,在Rebol中它非常简单:

代码语言:javascript
复制
foo: "test1"
set to-word (rejoin [foo "_result_data"]) some
print test1_result_data

但在球拍里我得用语法。所以我找到了像How do I define functions using Racket macros?Racket Macro to auto-define functions given a list这样的例子。它们涵盖了我需要的大量知识,因此我编写了下一个片段:

代码语言:javascript
复制
#lang racket
(require (for-syntax racket/syntax ffi/unsafe))

(define-for-syntax *method-names*
  ; Given I have hello, one and two methods in my shared lib
  (list "hello"
        "one"
        "two"
        ))

(define-syntax (define-ffi-func stx)
  (syntax-case stx ()
    [(_)
     (let ([elem->fn-id 
            (λ (elem-str)
              (format-id 
               stx "~a" 
               (datum->syntax stx (string->symbol elem-str))))]
            [rustlib
              (ffi-lib "/path/to/libffitest.dylib")
              ]
            )
       (with-syntax 
         ([((method cation) ...)
           (map 
            (λ (elem)
              ; I can load C code here for sure :) But not much more
              ; (define c (get-ffi-obj elem rustlib (_fun -> _int)
              ;  (lambda ()
              ;     (error 'rustlib
              ;      "installed lib does not provide given method"))))
              (list (elem->fn-id elem) elem)
            )
            *method-names*)])
         #`(begin
             (define (method) 
              ; I'm curious what should be here
                1
              )
             ...)))]))

(define-ffi-func)
; Actually one, two and hello methods are in scope
; but surely they all return 1
(two) 

但我还是不能把新的球拍方法和ffi联系起来。我想我无法在with-syntax中匹配它们,但是进一步的语法定义对外部模块一无所知。

代码语言:javascript
复制
#`(begin
    (define (ate) 
        (get-ffi-obj elem rustlib (_fun -> _int))
         )
     ...)))]))

都不管用。

我想我也错过了绑定匹配的一些东西。

如何通过指定名称列表来获得FFI绑定方法?提前感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-12 22:56:09

既然您已经回答了您的主要问题,我只想指出,通常使用字符串列表来表示名称并不是很糟糕。通常最好使用标识符。您实际需要动态计算这些字符串吗?

如果没有,那么编写一个宏来定义给定标识符列表的所有FFI绑定非常简单:

代码语言:javascript
复制
(define-syntax-rule (define-ffi-functions name ...)
  (begin (define name
           (get-ffi-obj (quote name) ffi-lib (_fun -> _int)))
         ...))

(define-ffi-functions hello one two)

ffi-lib有一个合适的定义。

票数 2
EN

Stack Overflow用户

发布于 2016-06-12 14:58:01

最后得到了这样的结果:

代码语言:javascript
复制
(define-for-syntax *method-names*
  (list "hello"
        "one"
        "two"
        ))

(define rustlib (ffi-lib "/path/to/Projects/libffitest.dylib"))

(define-syntax (define-ffi-func stx)
  (syntax-case stx ()
    [(_ lib ffi-func)
     (let ([elem->fn-id 
            (λ (elem-str)
              (format-id 
               stx "~a" 
               (datum->syntax stx (string->symbol elem-str))))]
            )
       (with-syntax 
         ([((method name) ...)
           (map 
            (λ (elem)
              (list (elem->fn-id elem) elem)
            )
            *method-names*)])
         #`(begin
             (define method
                (ffi-func name lib (_fun -> _int))
              )
             ...)))]))

(define-ffi-func rustlib get-ffi-obj)
(+ (one) (two))

仍然需要抛光,但总的来说是可以理解的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37764998

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档