Help to provide appropriate types for params

Can somebody help me with the params here? I have the first one(GIOChannel), but what about the others? AFAIC they are not rust types, how to call that function?

pub fn g_io_channel_read_line(
        channel: *mut GIOChannel,
        str_return: *mut *mut c_char,
        length: *mut size_t,
        terminator_pos: *mut size_t,
        error: *mut *mut GError,
    ) -> GIOStatus;

markdown code please:

pub fn g(....) {}

Hi, I've almost managed to provide all args to the fn. Last one left, GError.
The error I'm getting is this:>

expected raw pointer *mut *mut GError
found struct GError

How to get *mut *mut GError from GError? See line with comment.
Any help appreciated.

unsafe extern "C" fn watch_out_channel(
    channel: *mut GIOChannel,
    condition: u32,
    pointer: gpointer,
) -> gboolean {
    let c_string = CString::new("Very long long string").expect("CString::new failed");
    let raw: *mut c_char = c_string.into_raw();
    let size: GType;
    let terminator_pos: GType;
    let error: glib_sys::GError;//Here I create GError, but don't now how to pass *mut *mut GError
    glib_sys::g_io_channel_read_line(channel, &mut raw, &mut size, &mut terminator_pos, error);
    1
}

The error parameter is a *mut *mut GError; it should be a pointer to a variable which stores a *mut GError. The variable can be initialized with ptr::null_mut(). In case it helps, here's an example I came up with of using GLib.IOChannel via glib-sys:

use glib_sys::{GError, GIOChannel, GIOStatus};
use std::{
    error,
    ffi::{CStr, CString},
    os::raw::c_char,
    ptr, slice, str,
};

// SAFETY: If `error` is not null, it must point to an initialized `GError`.
unsafe fn into_message(error: *mut GError) -> String {
    assert!(!error.is_null());
    let message: &CStr = CStr::from_ptr((*error).message);
    let message: String = message.to_str().unwrap().to_owned();
    glib_sys::g_error_free(error);
    message
}

fn read_lines(filename: &str) -> Result<Vec<String>, Box<dyn error::Error>> {
    let filename: CString = CString::new(filename)?;
    let mut error: *mut GError = ptr::null_mut();
    let channel: *mut GIOChannel = unsafe {
        glib_sys::g_io_channel_new_file(filename.as_ptr(), b"r\0".as_ptr().cast(), &mut error)
    };
    if channel.is_null() {
        return Err(unsafe { into_message(error) }.into());
    }
    let mut lines: Vec<String> = Vec::new();
    loop {
        let mut line_raw: *mut c_char = ptr::null_mut();
        let mut length: usize = 0;
        let status: GIOStatus = unsafe {
            glib_sys::g_io_channel_read_line(
                channel,
                &mut line_raw,
                &mut length,
                ptr::null_mut(),
                &mut error,
            )
        };
        match status {
            glib_sys::G_IO_STATUS_ERROR => {
                unsafe { glib_sys::g_io_channel_unref(channel) };
                return Err(unsafe { into_message(error) }.into());
            }
            glib_sys::G_IO_STATUS_NORMAL => {
                let line_bytes: &[u8] = if length == 0 {
                    &[]
                } else {
                    unsafe { slice::from_raw_parts(line_raw.cast(), length) }
                };
                lines.push(str::from_utf8(line_bytes).unwrap().to_owned());
                unsafe { glib_sys::g_free(line_raw.cast()) };
            }
            glib_sys::G_IO_STATUS_EOF => break,
            glib_sys::G_IO_STATUS_AGAIN => {}
            _ => unreachable!(),
        }
    }
    unsafe { glib_sys::g_io_channel_unref(channel) };
    Ok(lines)
}

Thank you very much for your work and help. I'll try that tomorrow and hopefully will be able to have that onboard keyboard working.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.