[][src]Struct dlopen::wrapper::OptionalContainer

pub struct OptionalContainer<Api, Optional> where
    Api: WrapperApi,
    Optional: WrapperApi
{ /* fields omitted */ }

Container for a library handle and both obligatory and optional APIs inside one structure.

A common problem with dynamic link libraries is that they often have different versions and some of those versions have broader API than others. This structure allows you to use two APIs at the same time - one obligatory and one optional. If symbols of the optional API are found in the library, the optional API gets loaded. Otherwise the optional() method will return None.

#Example

#[macro_use]
extern crate dlopen_derive;
extern crate dlopen;
use dlopen::wrapper::{OptionalContainer, WrapperApi};

#[derive(WrapperApi)]
struct Obligatory<'a> {
    do_something: extern "C" fn(),
    global_count: &'a mut u32,
}

#[derive(WrapperApi)]
struct Optional{
    add_one: unsafe extern "C" fn (arg: i32) -> i32,
    c_string: * const u8
}

fn main () {
    let mut container: OptionalContainer<Obligatory, Optional> = unsafe {
        OptionalContainer::load("libexample.dylib")
    }.unwrap();
    container.do_something();
    *container.global_count_mut() += 1;

    match container.optional(){
        &Some(ref opt) => {
            let _result = unsafe { opt.add_one(5) };
            println!("First byte of C string is {}", unsafe{*opt.c_string});
        },
        &None => println!("The optional API was not loaded!")
    }
}

Note: For more complex cases (multiple versions of API) you can use WrapperMultiApi.

Methods

impl<Api, Optional> OptionalContainer<Api, Optional> where
    Api: WrapperApi,
    Optional: WrapperApi
[src]

pub unsafe fn load<S>(
    name: S
) -> Result<OptionalContainer<Api, Optional>, Error> where
    S: AsRef<OsStr>, 
[src]

Opens the library using provided file name or path and loads all symbols (including optional if it is possible).

pub unsafe fn load_self() -> Result<OptionalContainer<Api, Optional>, Error>[src]

Load all symbols (including optional if it is possible) from the program itself.

This allows a shared library to load symbols of the program it was loaded into.

pub fn optional(&self) -> &Option<Optional>[src]

Gives access to the optional API - constant version.

pub fn optional_mut(&mut self) -> &Option<Optional>[src]

Gives access to the optional API - constant version.

Trait Implementations

impl<Api, Optional> DerefMut for OptionalContainer<Api, Optional> where
    Api: WrapperApi,
    Optional: WrapperApi
[src]

impl<Api, Optional> Deref for OptionalContainer<Api, Optional> where
    Api: WrapperApi,
    Optional: WrapperApi
[src]

type Target = Api

The resulting type after dereferencing.

Auto Trait Implementations

impl<Api, Optional> Sync for OptionalContainer<Api, Optional> where
    Api: Sync,
    Optional: Sync

impl<Api, Optional> Send for OptionalContainer<Api, Optional> where
    Api: Send,
    Optional: Send

impl<Api, Optional> Unpin for OptionalContainer<Api, Optional> where
    Api: Unpin,
    Optional: Unpin

impl<Api, Optional> UnwindSafe for OptionalContainer<Api, Optional> where
    Api: UnwindSafe,
    Optional: UnwindSafe

impl<Api, Optional> RefUnwindSafe for OptionalContainer<Api, Optional> where
    Api: RefUnwindSafe,
    Optional: RefUnwindSafe

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]