gir icon indicating copy to clipboard operation
gir copied to clipboard

`from_glib_borrow` used for `c_int` makes type error

Open Ekleog opened this issue 4 years ago • 0 comments

The issue arises when using this .gir file https://ekleog.org/vrac/nOkXrcFNgD8Zrg-Aravis-0.6.gir .

Generating the -sys and then the regular bindings lead to errors like these:

error[E0277]: the trait bound `i32: glib::translate::Ptr` is not satisfied
  --> src/auto/device.rs:93:25
   |
93 |             let type_ = from_glib_borrow(type_);
   |                         ^^^^^^^^^^^^^^^^ the trait `glib::translate::Ptr` is not implemented for `i32`
   |
   = note: required by `glib::translate::from_glib_borrow`

error[E0277]: the trait bound `auto::enums::StreamCallbackType: glib::translate::FromGlibPtrBorrow<i32>` is not satisfied
  --> src/auto/device.rs:93:25
   |
93 |             let type_ = from_glib_borrow(type_);
   |                         ^^^^^^^^^^^^^^^^ the trait `glib::translate::FromGlibPtrBorrow<i32>` is not implemented for `auto::enums::StreamCallbackType`
   |
   = note: required by `glib::translate::from_glib_borrow`

The generated code is the following:

fn create_stream<P: FnMut(&StreamCallbackType, &Buffer)>(&self, callback: P) -> Option<Stream> {
    let callback_data: P = callback;
    unsafe extern "C" fn callback_func<P: FnMut(&StreamCallbackType, &Buffer)>(user_data: glib_sys::gpointer, type_: aravis_sys::ArvStreamCallbackType, buffer: *mut aravis_sys::ArvBuffer) {
        let type_ = from_glib_borrow(type_);
        let buffer = from_glib_borrow(buffer);
        let callback: *mut P = buffer as *const _ as usize as *mut P;
        (*callback)(&type_, &buffer);
    }
    let callback = Some(callback_func::<P> as _);
    let super_callback0: &P = &callback_data;
    unsafe {
        from_glib_full(aravis_sys::arv_device_create_stream(self.as_ref().to_glib_none().0, callback, super_callback0 as *const _ as usize as *mut _))
    }
}

With

pub type ArvStreamCallbackType = c_int;

The relevant part of the .gir are, I think:

      <method name="create_stream"
              c:identifier="arv_device_create_stream"
              version="0.2.0">
        <doc xml:space="preserve">Creates a new #ArvStream for video stream handling. See
@ArvStreamCallback for details regarding the callback function.</doc>
        <return-value transfer-ownership="full">
          <doc xml:space="preserve">a new #ArvStream.</doc>
          <type name="Stream" c:type="ArvStream*"/>
        </return-value>
        <parameters>
          <instance-parameter name="device" transfer-ownership="none">
            <doc xml:space="preserve">a #ArvDevice</doc>
            <type name="Device" c:type="ArvDevice*"/>
          </instance-parameter>
          <parameter name="callback"
                     transfer-ownership="none"
                     scope="call"
                     closure="1">
            <doc xml:space="preserve">a frame processing callback</doc>
            <type name="StreamCallback" c:type="ArvStreamCallback"/>
          </parameter>
          <parameter name="user_data" closure="1"
                     transfer-ownership="none"
                     nullable="1"
                     allow-none="1">
            <doc xml:space="preserve">user data for @callback</doc>
            <type name="gpointer" c:type="gpointer"/>
          </parameter>
        </parameters>
      </method>
    <callback name="StreamCallback" c:type="ArvStreamCallback">
      <return-value transfer-ownership="none">
        <type name="none" c:type="void"/>
      </return-value>
      <parameters>
        <parameter name="user_data"
                   transfer-ownership="none"
                   nullable="1"
                   allow-none="1"
                   closure="0">
          <type name="gpointer" c:type="gpointer"/>
        </parameter>
        <parameter name="type" transfer-ownership="none">
          <type name="StreamCallbackType" c:type="ArvStreamCallbackType"/>
        </parameter>
        <parameter name="buffer" transfer-ownership="none">
          <type name="Buffer" c:type="ArvBuffer*"/>
        </parameter>
      </parameters>
    </callback>
    <enumeration name="StreamCallbackType"
                 glib:type-name="ArvStreamCallbackType"
                 glib:get-type="arv_stream_callback_type_get_type"
                 c:type="ArvStreamCallbackType">
      <doc xml:space="preserve">Describes when the stream callback is called.</doc>
      <member name="init"
              value="0"
              c:identifier="ARV_STREAM_CALLBACK_TYPE_INIT"
              glib:nick="init">
        <doc xml:space="preserve">thread initialization, happens once</doc>
      </member>
      <member name="exit"
              value="1"
              c:identifier="ARV_STREAM_CALLBACK_TYPE_EXIT"
              glib:nick="exit">
        <doc xml:space="preserve">thread end, happens once</doc>
      </member>
      <member name="start_buffer"
              value="2"
              c:identifier="ARV_STREAM_CALLBACK_TYPE_START_BUFFER"
              glib:nick="start-buffer">
        <doc xml:space="preserve">buffer filling start, happens at each frame</doc>
      </member>
      <member name="buffer_done"
              value="3"
              c:identifier="ARV_STREAM_CALLBACK_TYPE_BUFFER_DONE"
              glib:nick="buffer-done">
        <doc xml:space="preserve">buffer filled, happens at each frame</doc>
      </member>
    </enumeration>

cc @GuillaumeGomez

Ekleog avatar Oct 21 '19 20:10 Ekleog