Paolo Bonzini <pbonzini@xxxxxxxxxx> writes: > On 30/11/20 16:30, Daniel P. Berrangé wrote: >> { 'struct': 'QCryptoSecretCommon', >> 'base': 'Object', >> 'state': { 'rawdata': '*uint8_t', >> 'rawlen': 'size_t' }, >> 'data': { '*format': 'QCryptoSecretFormat', >> '*keyid': 'str', >> '*iv': 'str' } } >> { 'struct': 'QCryptoSecret', >> 'base': 'QCryptoSecretCommon', >> 'data': { '*data': 'str', >> '*file': 'str' } } > > No, please don't do this. I want to keep writing C code, not a weird > JSON syntax for C. > > I'd much rather have a FooOptions field in my struct so that I can > just do visit_FooOptions in the UserCreatable.complete() method, > that's feasible. It should be, because it's what we've done elsewhere, isn't it? Yes, we can extend QAPI to let us embed opaques outside the QAPI schema's scope ("state"), along with means to create, destroy, and clone. This is new. But we can also invert: put the QAPI-generated C type ("config") in a handwritten C type that marries it to "state". Code to create and destroy is handwritten, and uses QAPI-generated code for the "config" part. A generic interface to handwritten creation is possible: Take the QAPI-generated "config" type as argument, extract enough information to call the appropriate constructor, return its value. Generic destruction is also possible: all it needs is a map from instance to destructor function. None of this is new in QEMU.