Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion: show example of passing a mutable slice #59

Open
mark-summerfield opened this issue Feb 9, 2018 · 2 comments
Open

Suggestion: show example of passing a mutable slice #59

mark-summerfield opened this issue Feb 9, 2018 · 2 comments

Comments

@mark-summerfield
Copy link

mark-summerfield commented Feb 9, 2018

For example, suppose you want to pass in f64s and have some computations produce resulting f64s. One way is to allocate both in the non-Rust language and then pass one as *const inputs and the other as *mut results. This avoids the need to dealloc in Rust.

For example, in Python:

InputType = ctypes.c_double * len(data)
ResultsType = ctypes.c_double * len(data)
inputs = InputType()
for i, x in enumerate(data): # InputType(*data) might fail if > 255 items
    inputs[i] = x
results = ResultsType()
dll.process(inputs, len(data), results)

And in Rust:

#[no_mangle]
pub extern fn process(inputs: *const c_double, size: uint32_t, results: *mut c_double) {
    let inputs = unsafe {
        assert!(!data.is_null());
        slice::from_raw_parts(inputs, size as usize)
    };
    let mut results = unsafe {
        assert!(!results.is_null());
        slice::from_raw_parts_mut(results, size as usize)
    };
    ...
}

Oh, and thank you for creating this web site in the first place: I have found it very useful!

@AmosEgel
Copy link

AmosEgel commented Sep 6, 2018

I was looking for that, too.
Thanks @mark-summerfield for providing that code snippet, it helped me a lot.
Does this approach have any disadvantages compared to allocating and deallocating the result in Rust (besides that one needs to know the size of the array in advance)?

@mark-summerfield
Copy link
Author

The approach shown passes just two pointers and an int to Rust, so there's virtually no call overhead.
If the data were created in Rust and returned to Python there'd be the overhead proportional to the size of the data since Python would have to copy the returned data before Rust frees it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants