无法创建 SinkInputInfo 数组

Cannot create an array of SinkInputInfo

我无法创建 SinkInputInfo 对象数组。我已经 posted this 到适当的回购但没有得到回应。

最小复制:

using PulseAudio;

public void main () {
    SinkInputInfo[] sink_inputs;
}

产出

/tmp/test.vala.PFQW80.c: In function ‘_vala_pa_sink_input_info_array_free’:
/tmp/test.vala.PFQW80.c:18:4: warning: implicit declaration of function ‘pulse_audio_sink_input_info_destroy’ [-Wimplicit-function-declaration]
   18 |    pulse_audio_sink_input_info_destroy (&array[i]);
      |    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/ld: /tmp/ccZQGm6J.o: in function `_vala_pa_sink_input_info_array_free':
test.vala.PFQW80.c:(.text+0x3f): undefined reference to `pulse_audio_sink_input_info_destroy'
collect2: error: ld returned 1 exit status
error: cc exited with status 256

您无法创建 SinkInputInfo 的实例。您也不能在任何地方存储它的实例。

原因是它只在回调中有效:

https://www.freedesktop.org/software/pulseaudio/doxygen/introspect.html#query_sec

Data members in the information structures are only valid during the duration of the callback. If they are required after the callback is finished, a deep copy of the information structure must be performed.

libpulse 不提供任何方法来复制或释放 SinkInputInfo 指针类型。

但是您可以在结构中使用任何东西:

Gee.ArrayList<string> sink_inputs;

public void cb(PulseAudio.Context c, PulseAudio.SinkInputInfo? i, int eol) {
        sink_inputs.add(i.name);
}

public void main () {
    var loop = new PulseAudio.MainLoop();
    var context = new PulseAudio.Context(loop.get_api(), null);
    sink_inputs = new Gee.ArrayList<string>();
    context.get_sink_input_info_list(cb);
}

这里我只存储了name属性。您可以通过在 vala 中创建自己的数据类型并复制您感兴趣的任何内容来扩展它。

另外vapi文件不完整,有办法告诉Vala编译器复制和内存管理不可用。参见 https://wiki.gnome.org/Projects/Vala/ManualBindings#Structs

我有一段时间没有编写任何 Vala 代码,但我认为 vapi 文件应该将 destroy_function 设置为空字符串。

总结:不要试图在任何地方存储回调的 SinkInputInfo 参数,只需复制您感兴趣的结构的字段即可。