Hi Yu, On Mon, Nov 9, 2009 at 7:12 PM, Feng Yu <rainwoodman gmail com> wrote:
On Sun, Oct 4, 2009 at 7:25 AM, Philipp Zabel <pzabel gmx de> wrote:Hi, Does anybody have example code that uses the ZLib bindings? I tried to implement the example described at http://zlib.net/zlib_how.html for inflation, but compilation failed with errors from gcc about STATUS_OK etc. symbols not being found. The following patch helped with that for some reason. Also, I don't understand how Vala can handle memory for the next_in and next_out pointers when the inflate call is changing those pointers under its nose. Wouldn't it be more realistic not to wrap them as an array?I believe old vapi binding for next_in and next_out still works. Vala don't manage the memory of struct types declared in vapi files. If you are sure the buffer is not owned by the struct and you want to explicitly mention this in the vapi file, use 'unowned'. Change the signature to 'unowned uchar[]' in this case.
Yes, you are right. With the following patch (against 0.7.8) ... diff --git a/vapi/zlib.vapi b/vapi/zlib.vapi index bb85db7..db9579d 100644 --- a/vapi/zlib.vapi +++ b/vapi/zlib.vapi @@ -90,10 +90,11 @@ namespace ZLib { } [CCode (cname = "z_stream", destroy_function = "deflateEnd")] public struct Stream { - public uchar* next_in; - public uint avail_in; + [CCode (array_length_cname = "avail_in", array_length_type = "guint")] + public weak uchar[] next_in; public ulong total_in; - public uchar* next_out; + [CCode (array_length_cname = "avail_out", array_length_type = "guint")] + public weak uchar[] next_out; public uint avail_out; public ulong total_out; public string? msg; .. I can also make my example work if I assign to the weak uchar array's length: InputStream source = File.new_for_path ("test.gz").read (null); uchar[] buf_in = new uchar[16384]; uchar[] buf_out = new uchar[16384]; var strm = InflateStream.full (15 | 32); // no way to check if this failed... strm.next_in = buf_in; strm.next_out = buf_out; strm.next_in.length = (int) source.read (strm.next_in, strm.next_in.length, null); // ^ ^ ^ ^ ^ ^ ^ here if (strm.next_in.length == 0) return; int ret = strm.inflate (Flush.NO_FLUSH); I still maintain that strm.next_in / strm.next_out cannot be owned arrays because the call to strm.inflate changes the pointers themselves. The same program compiles unchanged when I remove the weak keywords again, but it fails when trying to destroy the buffers: *** glibc detected *** ./zlibtest: munmap_chunk(): invalid pointer: 0x000000000210b500 ***
Please avoid pointers if possible in vapi bindings. Pointers forces programers write '->'s and makes the code C++-ish.
The '->' argument doesn't apply here - uchar* vs uchar[], no structs involved. But I agree that a single weak uchar[] is more Valaish than a uchar* and an int. The initial assignment is more compact this way: strm.next_out = buf_out; vs strm.next_out = buf_out; strm.avail_out = buf_in.length; And I have to replace strm.avail_out with stream.next_out.length. Other than that, it's the same. So should we change that back (to weak uchar[]s)?
Remember your vapi file is going to be used by others and will affect their programming styles. The influence might be permanent.
Thanks for having a look at this. regards Philipp
Attachment:
zlibtest.vala
Description: Text Data