Skip to content

Instantly share code, notes, and snippets.

@fidothe
Last active November 29, 2015 17:01
Show Gist options
  • Save fidothe/bf5cc5a917c2ca81bbcb to your computer and use it in GitHub Desktop.
Save fidothe/bf5cc5a917c2ca81bbcb to your computer and use it in GitHub Desktop.
Attempting to read a number out of an FFI struct-in-a-struct
use std::ffi::CString;
extern crate libc;
/* structs and enums-hiding-structs taken from libdvdread:
http://git.videolan.org/?p=libdvdread.git;a=blob;f=src/dvdread/dvd_reader.h;h=9c7be9d0d2dcaa7dd003b43ecc00fc791ffec657;hb=refs/heads/master
http://git.videolan.org/?p=libdvdread.git;a=blob;f=src/dvdread/ifo_read.h;h=97f4179f0ce95d00d1db0df136a0111a574e71a2;hb=refs/heads/master
http://git.videolan.org/?p=libdvdread.git;a=blob;f=src/dvdread/ifo_types.h;h=33f03467b375025ac78c0294e42c321df924ffae;hb=refs/heads/master
*/
pub enum DVDReader {}
pub enum DVDFile {}
pub enum VMGIManagementTable {}
pub enum PGCI {}
pub enum ParentalManagementInfoTable {}
pub enum VTSAttributeTable {}
pub enum TextDataManagerInfo {}
pub enum PGCIUnitTable {}
pub enum CellAddressTable {}
pub enum VOBUAddressMap {}
pub enum VTSIManagementTable {}
pub enum VTSPartOfTitleSearchPtrTable {}
pub enum PGCITable {}
pub enum VTSTimeMapTable {}
/*
The following structure defines an IFO file. The structure is divided into
two parts, the VMGI, or Video Manager Information, which is read from the
VIDEO_TS.[IFO,BUP] file, and the VTSI, or Video Title Set Information, which
is read in from the VTS_XX_0.[IFO,BUP] files.
*/
pub struct IFOHandle {
file: *const DVDFile,
/*const VMGI */
vmgi_mat: *const VMGIManagementTable,
tt_srpt : *const TitleSearchPtrTable,
first_play_pgc: *const PGCI,
ptl_mait: *const ParentalManagementInfoTable,
vts_atrt: *const VTSAttributeTable,
txtdt_mgi: *const TextDataManagerInfo,
/*const Common */
pgci_ut: *const PGCIUnitTable,
menu_c_adt: *const CellAddressTable,
menu_vobu_admap: *const VOBUAddressMap,
/*const VTSI */
vtsi_mat: *const VTSIManagementTable,
vts_ptt_srpt: *const VTSPartOfTitleSearchPtrTable,
vts_pgcit: *const PGCITable,
vts_tmapt: *const VTSTimeMapTable,
vts_c_adt: *const CellAddressTable,
vts_vobu_admap: *const VOBUAddressMap,
}
/*
* PartOfTitle Search Pointer Table.
typedef struct {
uint16_t nr_of_srpts;
uint16_t zero_1;
uint32_t last_byte;
title_info_t *title;
} ATTRIBUTE_PACKED tt_srpt_t;
*/
pub struct TitleSearchPtrTable {
nr_of_srpts: libc::c_ushort,
zero_1: libc::c_ushort,
last_byte: libc::c_uint,
title: *const TitleInfo,
}
/*
* Title Information.
typedef struct {
playback_type_t pb_ty;
uint8_t nr_of_angles;
uint16_t nr_of_ptts;
uint16_t parental_id;
uint8_t title_set_nr;
uint8_t vts_ttn;
uint32_t title_set_sector;
} ATTRIBUTE_PACKED title_info_t;
*/
pub enum TitleInfo {}
#[link(name = "dvdread")]
extern {
fn DVDOpen(path: *const libc::c_char) -> *const DVDReader;
fn ifoOpen(dvd: *const DVDReader, title: libc::c_int ) -> *const IFOHandle;
}
fn main() {
let path = CString::new("/path/to/dvd").unwrap();
unsafe {
let dvd = DVDOpen(path.as_ptr());
let ifo = ifoOpen(dvd, 0);
let title_info = &ifo.tt_srpt;
println!("DVD has {} titles", ifo.tt_srpt.nr_of_srpts);
}
println!("Didn't explode!");
}
$ cargo build
Compiling hello v0.0.1 (file:///path/to/project)
src/main.rs:90:27: 90:38 error: attempted access of field `tt_srpt` on type `*const IFOHandle`, but no field with that name was found
src/main.rs:90 let title_info = &ifo.tt_srpt;
^~~~~~~~~~~
src/main.rs:91:39: 91:50 error: attempted access of field `tt_srpt` on type `*const IFOHandle`, but no field with that name was found
src/main.rs:91 println!("DVD has {} titles", ifo.tt_srpt.nr_of_srpts);
@skade
Copy link

skade commented Nov 29, 2015

*const T will - to my knowledge - not be automatically dereferenced. (https://doc.rust-lang.org/std/ops/trait.Deref.html#is not implemented for *const T, only for &'a T)

Try

let title_info = &(*ifo.tt_srpt);

@fidothe
Copy link
Author

fidothe commented Nov 29, 2015

no 😦, it's the same error. (But thanks for taking a look!)

   Compiling hello v0.0.1 (file:///Users/matt/Documents/work/current/screener/screener-server)
src/main.rs:90:29: 90:40 error: attempted access of field `tt_srpt` on type `*const IFOHandle`, but no field with that name was found
src/main.rs:90         let title_info = &(*ifo.tt_srpt);
                                           ^~~~~~~~~~~

@fidothe
Copy link
Author

fidothe commented Nov 29, 2015

see https://github.com/fidothe/screener-server/ for the complete idiocy as cargo-buildable project

@skade
Copy link

skade commented Nov 29, 2015

Ooops, &(*ifo).tt_srpt; obviously. (Deref ifo, not deref &(*ifo.tt_srpt); )

@joecorcoran
Copy link

Looks like the confusing error message is an open issue: rust-lang/rust#11004

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment