Wrapping C in Rust is a two-stage process: first writing an "unsafe" FFI binding to the C API, which is usually almost completely automated with a crate called bindgen, then writing a "safe" crate that provides a Rust-y API using the unsafe FFI bindings. Wrapping C++ means writing a C API first, then binding that to Rust, which is what my crate does.
I've been meaning to return to this (and OSL, OpenSubdiv and others) at some point and try to make a project-specific C-binding generator using libclang, as manually maintaining the C stubs is laborious and error-prone. Scott, I'd be curious to know how you're getting on with cxx, I've been meaning to look into that. I'd be happy to collaborate on something we could integrate into the main project as Larry suggests. On Mon, 19 Oct 2020 at 12:30, Larry Gritz <[email protected]> wrote: > Feel free to have the discussion on-list, I'm sure it would be of interest > to many. > > If there was consensus on what the Rust APIs should look like, I would > welcome adding a set of Rust bindings to the main OIIO distribution. > Assuming that makes sense, I was thinking it would be much like we now have > with the Python bindings. The advantage to making Rust bindings part of the > main build would be that it could be built and tested as part of our CI, > versioned along with the rest of OIIO, and essentially never allowed to > break. Also, just like we would never accept a PR that added C++ > functionality without making sure the Python bindings kept up, we could > ensure that nothing is left out of the Rust bindings. While I can > appreciate the cleanliness and independence of it being a separate project, > I can't help but think that it will be a neverending nightmare to try to > keep the bindings in sync with the main project. > > I don't know how automated it is to make Rust bindings for C (I know it's > a PITA for C++), but if making Rust bindings is substantially easier if you > had minimal plain C wrappers for the major C++ classes, I'm sure there > would be a lot of happy consumers of that even outside the Rust interest > group. > > I haven't had time to try Rust myself for any programming project, though > I've followed it from afar and like the idea of helping that community. > TBH, the main thing that keeps me from spending any time on Rust is just > that I can't contemplate the hassle of trying to program without my > favourite libraries, and having OIIO (and its many utilities that I reuse > in basically everything I write) available in Rust will substantially lower > the bar for me to dabble in it more. > > -- lg > > > On Oct 18, 2020, at 4:12 PM, Scott Wilson <[email protected]> wrote: > > Hey Anders, > > We were inspired by what you did, and also decided to see if we can take > this in a slightly different direction/ use cxx. If you're interested in > discussing the wrapper more we can take it off the list. > > On Sun, Oct 18, 2020 at 3:35 PM Anders Langlands < > [email protected]> wrote: > >> I also have a rust binding here if you're interested: >> https://github.com/anderslanglands/oiio-rs >> >> On Sun, 18 Oct 2020 at 04:43, Scott Wilson <[email protected]> wrote: >> >>> Awesome, thank you very much! I'll try this out and see how badly I >>> break things. >>> >>> On Sat., Oct. 17, 2020, 1:02 a.m. Larry Gritz, <[email protected]> >>> wrote: >>> >>>> If you know the true legal extent of the memory allocation in which >>>> that data pointer is located (in this case, the beginning and ending of the >>>> vector, if you are passing a pointer to one of the elements of that >>>> vector), then I think you could certainly consider it an error if any of >>>> these addresses lay outside that buffer: >>>> >>>> data + xstride*width - 1 >>>> data + ystride*height - 1 >>>> data + ystride*(height - 1) + xstride*width - 1 >>>> data + zstride*depth >>>> data + zstride*(depth - 1) + ystride*height - 1 >>>> data + zstride*(depth - 1) + ystride*(height - 1) + xstride*width - >>>> 1 >>>> >>>> There may be a more succinct way to put that, but I think it covers all >>>> the cases of + and - strides. >>>> >>>> >>>> On Oct 17, 2020, at 12:42 AM, Scott Wilson <[email protected]> >>>> wrote: >>>> >>>> Thanks! I guess to come from this at a different angle, let's say I'm >>>> doing something like this: >>>> >>>> std::vector<uint8_t> pixels(10*10*3*1); >>>> ImageInput.read_image(TypeDesc::UINT8, @pixels[0]) >>>> >>>> Would there be a case where I could pick a stride value that would fall >>>> outside the pixels vector? >>>> >>>> PS: Thanks! I'm working on this with a friend, and hope to have >>>> something released in the near future. >>>> >>>> On Fri., Oct. 16, 2020, 11:47 p.m. Larry Gritz, <[email protected]> >>>> wrote: >>>> >>>>> Oops, my math was wrong (in an unimportant detail): If you are making >>>>> a mosaic of 16x5 of these 10x10 images, it is 80 small images you are >>>>> assembling in total, not 40. >>>>> >>>>> >>>>> On Oct 16, 2020, at 11:43 PM, Larry Gritz <[email protected]> wrote: >>>>> >>>>> The strides don't describe the size of the image, they are the spacing >>>>> in memory of where you want the values to be placed upon being read (or >>>>> taken from in order to write). There is no invalid set of strides, because >>>>> the caller might want them to end up anywhere in memory. >>>>> >>>>> Or am I misunderstanding? >>>>> >>>>> For a fully "contiguous" memory buffer where you intend for every >>>>> plane, scanline, pixel, and channel immediately follows the previous one, >>>>> then in our example the strides would be xstride=3, ystride=30, >>>>> zstride=300. (Though for a 2D image, the zstride is not used.) >>>>> >>>>> Here's an example of where you might have a stride range that is >>>>> wildly outside this: Let's say that you have 40 of these 10 x 10 x 3 x >>>>> uint8 image files and you are trying to read them in and assemble them >>>>> into >>>>> a single RGBA mosaic image of 16x5 x 4 x uint8 (the additional channel is >>>>> alpha, which you will separately fill in as 1.0 [or 255 uint8] because >>>>> it's >>>>> not in your RGB files). Here's a cartoon to illustrate this: >>>>> >>>>> +-----------------------------------------+ >>>>> | | | | | | | | | | | | | | | | | | | | | | >>>>> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| >>>>> | | | | | | | | | | | | | | | | | | | | | | >>>>> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| >>>>> | | | | | | | | | |X| | | | | | | | | | | | >>>>> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| >>>>> | | | | | | | | | | | | | | | | | | | | | | >>>>> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| >>>>> | | | | | | | | | | | | | | | | | | | | | | >>>>> +-----------------------------------------+ >>>>> >>>>> Each of my little grid cells is a 10x10 image. But that 10x10 image >>>>> denoted by the "X" needs to be placed in memory in the right portion of >>>>> the >>>>> 16x10 x 5x10 mosaic. So what are the strides we use for the read? Well, >>>>> the >>>>> xstride is 4 because we're making room for an alpha channel that wasn't >>>>> present in the file, the ystride is 640 (= 10*16*4), because each scanline >>>>> of the little 10x10 image that you read needs to be placed on the proper >>>>> scanline of the 160x50 mosaic you are assembling in memory. >>>>> >>>>> -- lg >>>>> >>>>> >>>>> P.S. Woo-hoo for making a Rust wrapper. I think that's a totally great >>>>> thing. >>>>> >>>>> >>>>> >>>>> On Oct 16, 2020, at 10:46 PM, Scott Wilson <[email protected]> >>>>> wrote: >>>>> >>>>> I'm experimenting with a Rust wrapper for OIIO, and had some questions >>>>> about the stride. >>>>> >>>>> Let's say I have an image that is 10x10 pixels, and 3 channels, and 1 >>>>> byte per channel. What strides would be invalid for that image? I'm >>>>> guessing that anything between -10 * 10 * 3 * 1 to 10 * 10 * 3 * 1 and the >>>>> AutoStride would be valid, and everything else may try to access memory >>>>> that isn't initialized. Is this assumption correct, or am I missing >>>>> something? >>>>> >>>>> Thanks! >>>>> _______________________________________________ >>>>> Oiio-dev mailing list >>>>> [email protected] >>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >>>>> >>>>> >>>>> -- >>>>> Larry Gritz >>>>> [email protected] >>>>> >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> Oiio-dev mailing list >>>>> [email protected] >>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >>>>> >>>>> >>>>> -- >>>>> Larry Gritz >>>>> [email protected] >>>>> >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> Oiio-dev mailing list >>>>> [email protected] >>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >>>>> >>>> _______________________________________________ >>>> Oiio-dev mailing list >>>> [email protected] >>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >>>> >>>> >>>> -- >>>> Larry Gritz >>>> [email protected] >>>> >>>> >>>> >>>> >>>> _______________________________________________ >>>> Oiio-dev mailing list >>>> [email protected] >>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >>>> >>> _______________________________________________ >>> Oiio-dev mailing list >>> [email protected] >>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >>> >> _______________________________________________ >> Oiio-dev mailing list >> [email protected] >> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >> > _______________________________________________ > Oiio-dev mailing list > [email protected] > http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org > > > -- > Larry Gritz > [email protected] > > > > > _______________________________________________ > Oiio-dev mailing list > [email protected] > http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >
_______________________________________________ Oiio-dev mailing list [email protected] http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
