1

Let's say I have a C function:

void func(char *buf, unsigned int *len);

To call it in Rust, I declared:

pub fn func(buf: *mut ::std::os::raw::c_char, len: *mut ::std::os::raw::c_uint) {
    unimplemented!()
}

Then I wrote another wrapper:

pub fn another_func() -> String {
    let mut capacity: u32 = 256;
    let mut vec = Vec::with_capacity(capacity as usize);
    unsafe {
        func(vec.as_ptr() as *mut c_char, &capacity as *mut c_uint)
    };
    String::from_utf8(vec).unwrap();
    unimplemented!()
}

But the compiler told me:

error[E0606]: casting `&u32` as `*mut u32` is invalid
   --> src/main.rs:...:28
    |
307 |                                  &capacity as *mut c_uint)

Why can't I cast capacity into *mut c_unit?

bleater
  • 4,415
  • 44
  • 45
Galaxy
  • 845
  • 6
  • 23
  • 2
    Please note, that `unsafe` in this case is not needed, because to cast something into a pointer is totaly safe, but dereferencing a pointer is unsafe. – hellow Oct 15 '18 at 07:47
  • 3
    Second note: you should accept a `size_t` instead of a `unsigned int` for sizes (of arrays) in C. See https://stackoverflow.com/questions/2550774/what-is-size-t-in-c – hellow Oct 15 '18 at 07:49
  • 2
    Third note: you have to use `#[no_mangle]` to disable name-mangling to be able to call it from C. – hellow Oct 15 '18 at 07:51
  • 1
    Fourth note: I suspect, that you want to modify the `vec` in the `func` function. Make sure, that you use `set_len` (which is unsafe) to set the length of the `Vec`. – hellow Oct 15 '18 at 07:55
  • @hellow Thanks man. For the second one: actually I need uint32_t here, but I do not want to include too much headers like `stdint.h` into the api header. `size_t` may be long, which is longer than uint32_t, not fit. – Galaxy Oct 15 '18 at 08:01
  • @hellow For first one: I will try. For 3rd: yeah I did something similar. For 4th: yeah I did. – Galaxy Oct 15 '18 at 08:09

1 Answers1

3

I had to make the reference mutable.

func(vec.as_ptr() as *mut c_char, &mut capacity as *mut c_uint)
Ted Klein Bergman
  • 7,245
  • 3
  • 20
  • 40
Galaxy
  • 845
  • 6
  • 23