在球拍中动态创建FFI方法 [英] Dynamically create FFI methods in Racket

查看:91
本文介绍了在球拍中动态创建FFI方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在考虑通过Racket中的FFI加载С/Rust/etc函数的想法.我想将函数名称列表指定为字符串,然后通过一些辅助函数加载它们.主要问题是从字符串创建标识符/单词.例如,在Rebol中非常简单:

I'm playing with idea of loading С/Rust/etc functions via FFI in Racket. I'd like to specify list of function names as strings and then just load them by some helper function. Main problem is creating identifier/word from a string. For example, it is very simple in Rebol:

foo: "test1"
set to-word (rejoin [foo "_result_data"]) some
print test1_result_data

但是在球拍中,我必须使用语法.因此,我找到了>如何使用Racket宏定义函数的示例? Racket宏,可以在给定一个列表.他们涵盖了我需要的很多知识,所以我写了下一个片段:

but in Racket I have to use syntax stuff. So I've found examples like How do I define functions using Racket macros? and Racket Macro to auto-define functions given a list. They cover a lot knowledge I need so I've written next snippet:

#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调用绑定新的Racket方法.我想我无法在with-syntax正文中将它们匹配,但是进一步的语法定义对外部模块一无所知(例如

But still I can't bond new Racket methods with ffi calls. I guess I can't match them in with-syntax body but further syntax definition knows nothing about external modules (e.g.

#`(begin
    (define (ate) 
        (get-ffi-obj elem rustlib (_fun -> _int))
         )
     ...)))]))

不起作用.

我想我也缺少有关绑定比赛的东西.

I think I'm missing something about binding match too.

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

How can I get FFI-bonded methods by specifying a list of names? Thanks in advance!

推荐答案

由于您已经回答了您的主要问题,我只想指出,使用字符串列表来表示名称通常并不是很容易.通常最好使用标识符.您实际上是否需要动态计算这些字符串?

Since you already answered your main question, I just wanted to note that it's not very Rackety in general to use lists of strings to represent names. It's usually better to use identifiers. Do you actually need to dynamically compute these strings?

如果不这样做,那么在给定标识符列表的情况下,编写宏来定义所有FFI绑定非常简单:

If you don't, then it's very simple to write a macro to define all the FFI bindings given a list of identifiers:

(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的适当定义.

这篇关于在球拍中动态创建FFI方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆