当您想使用Racket的D-Bus绑定(https://docs.racket-lang.org/dbus/index.html)时,您必须手动编写接口的定义 . D-bus协议由.xml文件定义,基本上为您提供带参数的方法名称及其类型定义 . 类型定义被编码为y = byte,s = string等.Xml文件示例:

<node>
  <interface name="com.test.Callable">
    <method name="TestMethod">
      <arg name="data_in" type="sa(yyd)" direction="in" /> ;; 
      <arg name="data_in2" type="y" direction="in" /> ;; 
      <arg name="data_out" type="i" direction="out" />

    </method>
  </interface></node>

在Racket的dbus中,必须连接所有带有direction = in的arg元素的类型字段并生成如下代码:

(define-dbus-interface dbus-interface<%> "com.test.Callable"
  (TestMethod "sa(yyd)y") ;; pay attention to this line
  )

现在,您可以根据需要在自己的类中实现此接口,并开始通过D-bus发送一些消息 .

问题是,您可以使用多个方法使用非平凡的参数,并且您可以轻易搞错,因此我想创建一个代码生成器,它将获取.xml文件的名称并自动生成接口(define-dbus-interface)的定义 .

到目前为止我的进展可以在这里找到:https://gitlab.com/Ondra009/dbus-interface这只是一个大约90行的文件 .

我想打这个电话:

(parse-xml/file "org.freedesktop.Avahi.ServiceBrowser.xml")

在我的测试文件上,我期待收到接口的定义 . 到目前为止,我能够解析文件并生成,我相信,是(define-dbus-interface ...)方法调用的正确语法 .

我认为这应该是最后一步,但在这里我陷入困境 . 我无法从顶层看到界面的定义 . 我得到的错误列表:

../../../.racket/6.10.1/pkgs/dbus/dbus/main.rkt:228:11: define: not allowed in an expression context in: (define org.freedesktop.DBus.Introspectable<%>/c (class/c (Introspect (->m any)) (TestMethod (->m string? (listof (list/c (integer-in 0 255) (integer-in 0 255) real?)) (integer-in 0 255) (cons/c (integer-in 0 255) (integer-in 0 255)) any))))

这显然是由dbus包本身完成的扩展,因为我生成的代码看起来像代码列表(define-dbus-inteface ...) .

所以我的问题可能是:

  • 我是否可以将此作为C-macro系统使用,其方式是调用完全被另一个定义替换,或者我必须将生成的代码绑定到某个标识符? (或者在一个文件中有更多接口定义的情况下的idetifiers列表 .

  • 如果是这样,我该如何实现呢?