Last active
November 29, 2015 17:01
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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!"); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ 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); |
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);
^~~~~~~~~~~
see https://github.com/fidothe/screener-server/ for the complete idiocy as cargo-buildable project
Ooops, &(*ifo).tt_srpt;
obviously. (Deref ifo
, not deref &(*ifo.tt_srpt);
)
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
*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