Reputation: 293
I'm trying to set up a Rust FFI for libsane, the Linux scanning library. Executing the sane_open
function returns the error code 4
indicating an invalid argument. I believe it has something to do with my parameter declaration.
// If successful, places a new handle in *h
// SANE_String_Const is const char* and SANE_Handle is void*
SANE_Status sane_open(SANE_String_Const devname, SANE_Handle *h);
Bindgen generates the following:
pub type SANE_String_Const = *const ::std::os::raw::c_char
pub type SANE_Handle = *mut ::std::os::raw::c_void
pub fn sane_open(devname: SANE_String_Const, handle: *mut SANE_Handle) -> SANE_Status;
Here is what I have done:
pub fn test_open() {
unsafe {
let mut version_code = 0;
let result = sane_init(&mut version_code, None);
assert_eq!(result, SANE_Status_SANE_STATUS_GOOD);
let mut handle: SANE_Handle = std::ptr::null_mut();
let dev = CString::new("net1;dev0").unwrap();
let result = sane_open(dev.as_ptr(), &mut handle);
assert_eq!(result, SANE_Status_SANE_STATUS_GOOD);
sane_close(handle);
sane_exit();
}
}
Note that bindgen
generates an Option<_>
type for the callback where None
means passing NULL
. My minimal working example in C works flawlessly:
/* Link with -l sane */
#include <sane/sane.h>
#include <stdio.h>
#include <assert.h>
int main() {
SANE_Int version_code = 0;
assert(sane_init(&version_code, NULL) == SANE_STATUS_GOOD);
SANE_Handle h;
SANE_Status r = sane_open("net1;dev0", &h);
printf("Result: %d\n", r);
if(r == 0)
sane_close(h);
sane_exit();
}
What's wrong? Why does my Rust code behave differently?
Upvotes: 2
Views: 307