Files
ansi_term
arraydeque
atty
bear_lib_terminal
bear_lib_terminal_sys
bitflags
cfg_if
clap
const_cstr
dirs
dirs_sys
dlopen
dlopen_derive
downcast_rs
lazy_static
libc
num_traits
pir_8_as
pir_8_disasm
pir_8_emu
proc_macro2
quote
serde
serde_derive
strsim
syn
textwrap
time
tinyfiledialogs
toml
unicode_width
unicode_xid
vec_map
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use super::super::err::Error;
use super::super::raw::Library;

/**
Trait for defining library API.

This trait is intended to be used with `#[derive(WrapperApi)]` macro defined in the
`dlopen_derive` crate. It forces several restrictions on types that implement it:

* Only structures can implement this trait.
* All fields need to be private.
* Only functions, references and pointers are allowed.
* You can't define a type using `type Fun =fn();` and use it in the structure. This is a limitation
    of the Rust reflection mechanism. Only raw functions, references and pointers are allowed.
* All arguments of functions need to be named.


The `derive` macro not only generates implementation of `load()` function, but it also generates
safe wrappers around the loaded symbols. These wrappers are named exactly like the field that
they wrap. Wrappers of functions have the same arguments like original functions and wrappers of
references are just simple accessors in the form of `<field_name>(&self) -> &FieldType` or
`<field_name>_mut(&mut self) -> &mut FieldType`.
Wrappers are not generated only for:

* Pointers - there is no safe way of preventing dangling symbols if a user has a direct access to
    pointers. The recommended approach here is to either use references instead of pointers or
    to manually create safe wrappers. For example C `const char *` can be manually converted into
    `& std::ffi::CStr`.
* Variadic functions. Rust doesn't have any mechanism that allows creating safe wrappers around
    them. You need to handle them manually.

#Example

```no_run
#[macro_use]
extern crate dlopen_derive;
extern crate dlopen;
extern crate libc;
use dlopen::wrapper::{WrapperApi, Container};
use libc::{c_char};
use std::ffi::CStr;

#[derive(WrapperApi)]
struct Example<'a> {
    #[dlopen_name="function"]
    do_something: extern "C" fn(),
    add_one: unsafe extern "C" fn (arg: i32) -> i32,
    global_count: &'a mut u32,
    c_string: * const c_char,
    #[dlopen_allow_null]
    maybe_null_ptr: * const (),
}

//wrapper for c_string won't be generated, implement it here
impl<'a> Example<'a> {
    pub fn c_string(&self) -> &CStr {
        unsafe {CStr::from_ptr(self.c_string)}
    }
}

fn main () {
    let mut cont: Container<Example> = unsafe { Container::load("libexample.dylib")}.unwrap();
    cont.do_something();
    let _result = unsafe { cont.add_one(5) };
    *cont.global_count_mut() += 1;
    println!("C string: {}", cont.c_string().to_str().unwrap())
}
```

**Note**: `WrapperApi` should only be used together with `Container` structure, never to create
a standalone object. API and library handle need to be kept together to prevent dangling symbols.

**Note:** By default obtained symbol name is the field name. You can change this by
assigning the "dlopen_name" attribute to the given field.

**Note:** By default `Error::NullSymbol` is returned if the loaded symbol name has a null value.
While null is a valid value of a exported symbol, it is usually not expected by users of libraries.
If in your scenario null is an acceptable value, you should assign
"dlopen_allow_null" attribute to the given field. Of course this makes sense only if the field
is of pointer type.
*/
pub trait WrapperApi
where
    Self: Sized,
{
    ///Load symbols from provided library.
    unsafe fn load(lib: &Library) -> Result<Self, Error>;
}