In cases like this the normal thing to do is to make the C structures private and expose an abstract interface. Check out my zeromq binding, it might be helpful:
https://github.com/erickt/rust-zmq/blob/master/zmq.rc In your case with xmlParseFile, I would suggest not returning a pointer at all, but return an value with the C structure hidden inside of it with a destructor to free any memory associated with it. That will allow someone to mutate it or store it into various boxes: let mut doc1 = xmlParseFile("text.xml"); let doc2 = ~xmlParseFile("text.xml"); let doc3 = @mut xmlParseFile("text.xml"); On Sat, May 25, 2013 at 5:04 AM, Thomas Leonard <tal...@gmail.com> wrote: > On 25 May 2013 12:03, Benjamin Herr <b...@0x539.de> wrote: > > On Sat, 2013-05-25 at 11:09 +0100, Thomas Leonard wrote: > >> Hi, > > > > Hi! > > > >> I'm trying to interface to some C code which uses a lot of structs. I > >> can declare these using raw pointers, but then I lose the benefits of > >> Rust's compile-time pointer checking. So I tried replacing the raw > >> pointers with owned pointers, which more accurately captures the > >> meaning of the C interface. But when I do this, the pointers get > >> offset by 32 bytes. > >> > >> [...] > > > > Yeah, there's currently some overhead for owned boxes. From what I > > understand, they share the structure of the refcounted managed boxes > > with most of the fields nulled out (there's a struct to that effect in > > https://github.com/mozilla/rust/blob/incoming/src/libstd/managed.rs#L17 > > I believe). > > > > I figure this is because managed boxes were there first, and owned boxes > > kind of grew out of them, and this is going to change eventually when > > someone gets around to it... > > Oh, OK. > > >> For example, I'd like to replace this: > >> > >> struct xmlNode { > >> name: *i8, > >> ... > >> } > >> > >> with: > >> > >> struct CString; > >> > >> struct xmlNode { > >> name: ~CString, > >> ... > >> } > >> > >> Then I could (I assume) define safe functions on my CString type (len, > >> eq, etc) and not have to worry about memory leaks, etc when using them > >> from safe code. > >> > >> Is this possible? > > > > I don't believe this is possible in general even accounting for the box > > headers somehow because rust isn't promising what malloc/free > > implementation it is using for owned pointers. > > Wouldn't that be up to the constructor/finalizer for CString (if any)? > > But in this case, the way you use the API is: > > let doc: ~XmlDoc = xmlParseFile("test.xml"); > let cur: &xmlNode = xmlDocGetRootElement(doc); > > XmlDoc is a Rust struct which wraps the C one, freeing the whole > document when done. xmlNode is the actual C struct. > > So you never get a ~xmlNode, just a borrowed &xmlNode, and therefore > Rust should never try to free any items that were allocated by the C > library. Code using the library should be able to explore the tree > freely within the lifetime of the borrowed root node, I think. > > On the other hand, providing mutable access might require a different > API. If CString had constructors and destructors then they could > ensure that they used malloc/free, and maybe then allow direct access > to the C struct. Or maybe all mutations should go via wrapper > functions. > > > Maybe someone else has a better idea, but you could wrap the unsafe > > pointer into a struct with a safe interface and an impl for the Drop > > trait that calls libc's free() for much the same semantics, if a bit > > more awkward syntax. I think a type like this ought to be in libextra at > > some point, but I don't think there is yet. > > > > https://github.com/mozilla/rust/blob/incoming/src/libextra/rc.rs does > > something similar with refcounting instead of unique ownership > > semantics, maybe that's a starting point. > > > Thanks, > > -- > Dr Thomas Leonard http://0install.net/ > GPG: 9242 9807 C985 3C07 44A6 8B9A AE07 8280 59A5 3CC1 > GPG: DA98 25AE CAD0 8975 7CDA BD8E 0713 3F96 CA74 D8BA > _______________________________________________ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev >
_______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev