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

Reply via email to