On 22/09/20 18:35, Marc-André Lureau wrote: > The D-Bus specification doesn't detail versioning much. What is > recommended is to have the version number as part of the interface name > (kinda like soname): > http://0pointer.de/blog/projects/versioning-dbus.html (this is > documented in several places iirc) > > So a QEMU D-Bus interface could have a name like org.qemu.Qemu51, > org.qemu.Qemu52.. for example, if we can't provide better API stability...
That would be a problem for backports. It seems to me that the bindings issue is only a problem if we insist on having positional arguments like we do for C, but if we can avoid functions with a zillion arguments we could. For example in Rust, it's idiomatic to use the builder pattern let thread = thread::Builder::new() .name("foo".into()) .stack_size(65536) .spawn(run_thread)?; thread.join()?; and I think the same would work in Go or even C++. It would look like qapi::qga::commands::GuestShutdown::new() .mode("halt") .invoke_on(qapi_channel)?; with some kind of double dispatch implementation: trait QAPIChannel { ... fn invoke(command: dyn QAPISerialization) -> dyn QAPISerialization; } impl GuestShutdown { fn<T: QAPIChannel> invoke_on(t: T) -> () { let args = self.as_qapi_serialization(); t.invoke(args); // could "return from_qapi_serialization(result)", likewise } } In Python, you can use keyword arguments and there are even keyword-only arguments ("def f(*, key1, key2)"), like qapi.qga.GuestFileOpen(path="/etc/passwd").invoke_on(qapi_channel); When you do something like this QMP-style APIs are not a problem. FlatBuffers is another serialization format that supports this kind of extensibility (https://google.github.io/flatbuffers/ explicitly compares it to JSON, even). Paolo