在 vapi 文件中创建信号



我正在尝试编写一个VAPI文件以在Vala中使用libui (https://github.com/andlabs/libui)。

我不知道如何将来自控件的事件连接到 vala 信号。

在libui headers中,例如关闭窗口,此方法定义了:

_UI_EXTERN void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *w, void *data), void *data);  

在 C 示例中,此方法以方法 "onClosesing" 作为参数调用:

uiWindowOnClosing(w, onClosing, NULL);  

我怎样才能做出类似的东西:

window.OnClosing.connect(()=>{print("End");});

Vala 中的信号是使用 GLib 的信号实现的,这是观察者模式的一个例子。要在 Vala 中使用信号,该类需要从 Object 继承,看起来libui并没有使用 GLib 的 GObject。因此,无法在此绑定中使用信号。尽管可以在 Vala 绑定中使用信号。例如,gtksourceview VAPI绑定了SourceBufferredoundo信号。

uiWindowOnClosing中使用的模式是传递一个 C 函数指针以用作回调。在瓦拉方面,这些被称为代表。 libui 没有为功能点添加 typedef,所以 Vala 需要生成它。这是通过在 VAPI 中使用[CCode (has_typedef = false)]来指示的。

这里的另一个问题是用户数据的 void 指针 - void *data 。这可能最好使用简单的泛型来绑定。

装订处的粗略切割将是:

[CCode (cname = "uiWindow")]
public class Window {
  [CCode (has_typedef = false, simple_generics = true)]
  public delegate int Callback<T> (T data);
  [CCode (cname = "uiWindowOnClosing", simple_generics = true)]
  public void on_closing<K> (Callback callback, K data);
}

这是未经测试的,但应该可以让您更好地了解基本概念。

是不可能的。Vala的signal机制基于GLib的信号系统。你可以让这些使用 lambda,但不能使用信号。

vapi 中使用您的代码并用这个调用它:

w.on_closing(()=>{Quit();return 0;}, null);  

带来以下消息:

error: too many arguments to function ‘uiWindowOnClosing’
uiWindowOnClosing (_tmp3_, ___lambda4__ui_window_callback, NULL, NULL);

但这有效:

public void on_closing (Callback callback);  

在 vapi 中,以及

w.on_closing(()=>{Quit();return 0;});  

在瓦拉代码中。

谢谢你的帮助。

最新更新