So, there’s a rust crate I may or may not have to add to a project, depending on how the rest of the decision goes.
I have yet to make a decision, and this is part of the info-gathering stage of deciding.
This rust crate seems to be just a C library wrapped in Rust bindings, but in every way that matters, I am effectively calling direct C code.
Some of this code returns pointers to allocated memory. I do not know if it uses the same memory allocation system as Rust (intuition has me assuming that it does not).
I’m guessing I cannot just wrap this pointer in a Box and call it a day. My current assumption here is I would need to create my own struct that hooks the C code’s allocation and destruction functions into Rust’s memory handling.
It feels like I am effectively not working with actual Rust bindings here; I’m working with the thinnest possible membrane, wrapped around C code, so I still need to connect this bridge the rest of the way.
EDIT: Sorry, this might be a dumb place to ask such a question, but I really do not like the user environment of Stack Overflow, and I’m not entirely sure if I’m going to get a constructive answer on the Rust forum, which is not some version of “do not use this crate” when I cannot find an alternative.
A a quick glance, the library offers paired create/destroy functions (opus_decoder_create(), opus_decoder_destroy()) and expects you to call both. So you’re right: you can’t stick it into a Box. You need a Rust type which will call opus_decoder_destroy() in its own finalizer. It’s been a few months since I wrote any Rust, but I’m sure this would be a few lines of code.
Now, there’s an additional function opus_decoder_init() which says “This is intended for applications which use their own allocator instead of malloc.” You could use Rust’s allocator for that. I don’t know the idiom, though, and it wouldn’t really save you more than those few lines.
Thank you for your insight. This helped everything click into place for my brain…!
I’m inclined to strongly agree with you!
It looks like the way forward, then, is – as you said – to wrap this up in a custom Rust type, which calls opus_decoder_create() and opus_decoder_destroy() in its constructor and finalizer.
Thanks again for weighing in. I think I was getting overwhelmed by a number of environmental factors, and pushing myself to try comprehending this crate was perhaps not the task to try at the time; it was all making me feel very lost, lol. I’m glad I asked for help!
Rust still uses the system allocator (unless you tell it not to). The issue is that Rust automatically unallocates and C doesn’t, so to handle C allocations you have to explicitly call functions. It’s just like the Glk API where you create a stream and later close it. If you used Glk from Rust you’d still need to call these functions.
Ah, so when using C code from Rust (in this crate or otherwise), I still need to follow the same memory management steps that I would in C. Noted, thank you!
Belated, but: one perspective is that Rust-the-language doesn’t automatically deallocate the memory - but it provides the basic primitives you need to do that reliably (Drop implementations that always get called) and the standard library and pretty much every other library does the right thing, so as a Rust programmer you almost never need to care.
An exception is exactly this sort of library, which provides a very literal Rust repackaging of some external C/C++ API. In the community, the xxx-sys naming pattern like this crate has is used to signal that this is a low-level wrapper, and folks often provide a separate xxx crate that bundles stuff up into higher-level APIs that use more normal Rust patterns and things. (It looks like libopusenc is such a crate, though I don’t know if it has the stuff you need.) IIUC people do this sort of split because sometimes folks have different ideas about the “best” way to hide the gnarly C API behind a nice rust API, and for various reasons it sucks if you have two different libraries that wrap the same C code…
Anyways likely you already figured this stuff out, and your plan makes sense to me; just typing it out in case you or some other reader finds it useful.