1

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

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

在 libui 头文件中,例如关闭窗口,此方法定义:

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

在 C 示例中,使用方法“onClosing”作为参数调用此方法:

uiWindowOnClosing(w, onClosing, NULL);  

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

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

3 回答 3

2

Vala 中的信号是使用 GLib 的信号实现的,这是观察者模式的一个例子。要在 Vala 中使用信号,该类需要继承Object,它看起来不像libui使用 GLib 的 GObject。所以不可能在这个绑定中使用信号。虽然可以在 Vala 绑定中使用信号。例如gtksourceview VAPI绑定. redo_undoSourceBuffer

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

这里的另一个问题是用户数据的 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);
}

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

于 2019-01-12T13:33:52.063 回答
1

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

于 2019-01-11T17:03:28.763 回答
0

在 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;});  

在vala代码中。

谢谢您的帮助。

于 2019-01-19T13:13:59.567 回答