On Sat, 2015-11-21 at 20:48 -0600, Aaron Paden wrote: > On Sat, Nov 21, 2015 at 6:33 AM, Al Thomas <astav...@yahoo.co.uk> > wrote: > > > > > > This looks complex so I can only give a few pointers. > > > > Does the code actually compile or are you getting an error about an > > unresolved symbol? > > Right, the code compiles, but the linker fails because of the > unresolved symbols. I didn't think of this before, but the minimal > example is pretty simple: > > void main() { > PulseAudio.SourceInfo info; > } > > You can solve this by declaring info unowned. Clearly the issue is > that vala is managing SourceInfo when it shouldn't be managed, but I > wasn't sure how to actually fix this given how the API is actually > used. Ideally, the vapi itself should indicate that the struct is > unmanaged, but I'm not sure how to do that as of yet.
That's not quite right; the VAPI shouldn't indicate that a *type* is "unmanaged"… it's up to your code to indicate whether an instance is unowned. However, the question is really what the proper way to destroy an instance is. In order to determine how to destroy a struct which doesn't specify a destroy_function CCode attribute, Vala will look at the members. If none of the members require destroy or free functions, then Vala can assume that simply releasing the memory associated with the struct itself (i.e., calling g_free on heap-allocated instances, or simply allowing stack-allocated instances to go out of scope) is sufficient. For example, consider the following two structs: public struct Foo { public int foo_value; } public struct Bar { public string bar_value; } In this case, in order to destroy Foo nothing special is required. However, to destroy Bar g_free must be called on the bar_value field. That is where "unowned" comes into play. If the bar_value field had been marked as "unowned" then Vala would know that nothing special is required to free it. If you don't provide a destroy_function CCode annotation but Vala determines that it is necessary to call one, it will default to lower_case_cprefix_destroy, which is why it is generating a call to pulse_audio_source_info_destroy. The idea is recursive; if Foo had an owned Bar member then foo would require a destroy function (which would call Bar's destroy function on the appropriate field). On the other hand, if Foo had an owned field that contained another struct which didn't require a destroy function then that wouldn't cause Foo to require one, either. So, the right thing to do is probably to make any fields which require a destroy or free function unowned. However, this does have some implications; if you transfer ownership of an instance to Pulse Audio, and there is code in the library which calls a free function (such as g_free) on one of the fields, you'll likely end up with a double free. That behavior would be pretty unlikely; at that point I would argue that it is really a bug in the API (unless there is actually a destroy function but nobody told Vala about it). -Evan _______________________________________________ vala-list mailing list vala-list@gnome.org https://mail.gnome.org/mailman/listinfo/vala-list