Files
phy/dlib/index.html
Orion Kindel 0ce894e6b0 doc
2025-03-18 10:30:23 -05:00

97 lines
12 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="dlib is a small crate providing macros to make easy the use of external system libraries that can or cannot be optionally loaded at runtime, depending on whether a certain feature is enabled."><title>dlib - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-42caa33d.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="dlib" data-themes="" data-resource-suffix="" data-rustdoc-version="1.84.0 (9fc6b4312 2025-01-07)" data-channel="1.84.0" data-search-js="search-92e6798f.js" data-settings-js="settings-0f613d39.js" ><script src="../static.files/storage-59e33391.js"></script><script defer src="../crates.js"></script><script defer src="../static.files/main-5f194d8c.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../dlib/index.html">dlib</a><span class="version">0.5.2</span></h2></div><div class="sidebar-elems"><ul class="block"><li><a id="all-types" href="all.html">All Items</a></li></ul><section id="rustdoc-toc"><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#usage" title="Usage">Usage</a></li><li><a href="#remaining-generic-in-your-crate" title="Remaining generic in your crate">Remaining generic in your crate</a></li></ul><h3><a href="#macros">Crate Items</a></h3><ul class="block"><li><a href="#macros" title="Macros">Macros</a></li><li><a href="#enums" title="Enums">Enums</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Crate <span>dlib</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/dlib/lib.rs.html#1-386">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>dlib is a small crate providing macros to make easy the use of external system libraries that
can or cannot be optionally loaded at runtime, depending on whether a certain feature is enabled.</p>
<h3 id="usage"><a class="doc-anchor" href="#usage">§</a>Usage</h3>
<p>dlib defines the <code>external_library!</code> macro, which can be invoked in this way:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="macro">external_library!</span>(feature=<span class="string">"dlopen-foo"</span>, Foo, <span class="string">"foo"</span>,
statics:
me: c_int,
you: c_float,
functions:
<span class="kw">fn </span>foo() -&gt; c_int,
<span class="kw">fn </span>bar(c_int, c_float) -&gt; (),
<span class="kw">fn </span>baz(<span class="kw-2">*const </span>c_int) -&gt; c_int,
varargs:
<span class="kw">fn </span>blah(c_int, c_int ...) -&gt; <span class="kw-2">*const </span>c_void,
<span class="kw">fn </span>bleh(c_int ...) -&gt; (),
);</code></pre></div>
<p>As you can see, it is required to separate static values from functions and from function
having variadic arguments. Each of these 3 categories is optional, but the ones used must appear
in this order. Return types of the functions must all be explicit (hence <code>-&gt; ()</code> for void functions).</p>
<p>If the feature named by the <code>feature</code> argument (in this example, <code>dlopen-foo</code>) is absent on your crate,
this macro will expand to an extern block defining each of the items, using the third argument
of the macro as a link name:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="attr">#[link(name = <span class="string">"foo"</span>)]
</span><span class="kw">extern </span><span class="string">"C" </span>{
<span class="kw">pub static </span>me: c_int;
<span class="kw">pub static </span>you: c_float;
<span class="kw">pub fn </span>foo() -&gt; c_int;
<span class="kw">pub fn </span>bar(<span class="kw">_</span>: c_int, <span class="kw">_</span>: c_float) -&gt; ();
<span class="kw">pub fn </span>baz(<span class="kw">_</span>: <span class="kw-2">*const </span>c_int) -&gt; c_int;
<span class="kw">pub fn </span>blah(<span class="kw">_</span>: c_int, <span class="kw">_</span>: c_int, ...) -&gt; <span class="kw-2">*const </span>c_void;
<span class="kw">pub fn </span>bleh(<span class="kw">_</span>: c_int, ...) -&gt; ();
}
</code></pre></div>
<p>If the feature named by the <code>feature</code> argument is present on your crate, it will expand to a
<code>struct</code> named by the second argument of the macro, with one field for each of the symbols defined;
and a method <code>open</code>, which tries to load the library from the name or path given as an argument.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">pub struct </span>Foo {
<span class="kw">pub </span>me: <span class="kw-2">&amp;</span><span class="lifetime">'static </span>c_int,
<span class="kw">pub </span>you: <span class="kw-2">&amp;</span><span class="lifetime">'static </span>c_float,
<span class="kw">pub </span>foo: <span class="kw">unsafe extern </span><span class="string">"C" </span><span class="kw">fn</span>() -&gt; c_int,
<span class="kw">pub </span>bar: <span class="kw">unsafe extern </span><span class="string">"C" </span><span class="kw">fn</span>(c_int, c_float) -&gt; (),
<span class="kw">pub </span>baz: <span class="kw">unsafe extern </span><span class="string">"C" </span><span class="kw">fn</span>(<span class="kw-2">*const </span>c_int) -&gt; c_int,
<span class="kw">pub </span>blah: <span class="kw">unsafe extern </span><span class="string">"C" </span><span class="kw">fn</span>(c_int, c_int, ...) -&gt; <span class="kw-2">*const </span>c_void,
<span class="kw">pub </span>bleh: <span class="kw">unsafe extern </span><span class="string">"C" </span><span class="kw">fn</span>(c_int, ...) -&gt; (),
}
<span class="kw">impl </span>Foo {
<span class="kw">pub unsafe fn </span>open(name: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Result</span>&lt;Foo, DlError&gt; { <span class="comment">/* ... */ </span>}
}</code></pre></div>
<p>This method returns <code>Ok(..)</code> if the loading was successful. It contains an instance of the defined struct
with all of its fields pointing to the appropriate symbol.</p>
<p>If the library specified by <code>name</code> could not be openened, it returns <code>Err(DlError::CantOpen(e))</code>, with
<code>e</code> the error reported by <code>libloading</code> (see <a href="enum.LibLoadingError.html" title="enum dlib::LibLoadingError">LibLoadingError</a>);</p>
<p>It will also fail on the first missing symbol, with <code>Err(DlError::MissingSymbol(symb))</code> where <code>symb</code>
is a <code>&amp;str</code> containing the missing symbol name.</p>
<p>Note that this method is unsafe, as loading (and unloading on drop) an external C library can run arbitrary
code. As such, you need to ensure that the specific library you want to load is safe to load in the context
you want to load it.</p>
<h3 id="remaining-generic-in-your-crate"><a class="doc-anchor" href="#remaining-generic-in-your-crate">§</a>Remaining generic in your crate</h3>
<p>If you want your crate to remain generic over dlopen vs. linking, simply add a feature to your <code>Cargo.toml</code>:</p>
<div class="example-wrap"><pre class="language-toml"><code>[dependencies]
dlib = &quot;0.5&quot;
[features]
dlopen-foo = []</code></pre></div>
<p>Then give the name of that feature as the <code>feature</code> argument to dlibs macros:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="macro">external_library!</span>(feature=<span class="string">"dlopen-foo"</span>, Foo, <span class="string">"foo"</span>,
functions:
<span class="kw">fn </span>foo() -&gt; c_int,
);</code></pre></div>
<p><code>dlib</code> provides helper macros to dispatch the access to foreign symbols:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="macro">ffi_dispatch!</span>(feature=<span class="string">"dlopen-foo"</span>, Foo, function, arg1, arg2);
<span class="macro">ffi_dispatch_static!</span>(feature=<span class="string">"dlopen-foo"</span>, Foo, my_static_var);</code></pre></div>
<p>These will expand to the appropriate value or function call depending on the presence or absence of the
<code>dlopen-foo</code> feature on your crate.</p>
<p>You must still ensure that the functions/statics or the wrapper struct <code>Foo</code> are in scope. For example,
you could use the <a href="https://crates.io/crates/lazy_static"><code>lazy_static</code></a> crate to do the initialization,
and store the wrapper struct in a static variable that you import wherever needed:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="attr">#[cfg(feature = <span class="string">"dlopen-foo"</span>)]
</span><span class="macro">lazy_static::lazy_static!</span> {
<span class="kw">pub static </span><span class="kw-2">ref </span>FOO_STATIC: Foo =
Foo::open(<span class="string">"libfoo.so"</span>).ok().expect(<span class="string">"could not find libfoo"</span>);
}</code></pre></div>
<p>Then, it can become as simple as putting this on top of all modules using the FFI:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="attr">#[cfg(feature = <span class="string">"dlopen-foo"</span>)]
</span><span class="kw">use </span>ffi::FOO_STATIC;
<span class="attr">#[cfg(not(feature = <span class="string">"dlopen-foo"</span>))]
</span><span class="kw">use </span>ffi::<span class="kw-2">*</span>;</code></pre></div>
</div></details><h2 id="macros" class="section-header">Macros<a href="#macros" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="macro" href="macro.external_library.html" title="macro dlib::external_library">external_<wbr>library</a></div><div class="desc docblock-short">Main macro of this library, used to generate the the FFI bindings.</div></li><li><div class="item-name"><a class="macro" href="macro.ffi_dispatch.html" title="macro dlib::ffi_dispatch">ffi_<wbr>dispatch</a></div><div class="desc docblock-short">Macro for generically invoking a FFI function</div></li><li><div class="item-name"><a class="macro" href="macro.ffi_dispatch_static.html" title="macro dlib::ffi_dispatch_static">ffi_<wbr>dispatch_<wbr>static</a></div><div class="desc docblock-short">Macro for generically accessing a FFI static</div></li></ul><h2 id="enums" class="section-header">Enums<a href="#enums" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="enum" href="enum.DlError.html" title="enum dlib::DlError">DlError</a></div><div class="desc docblock-short">An error generated when failing to load a library</div></li><li><div class="item-name"><a class="enum" href="enum.LibLoadingError.html" title="enum dlib::LibLoadingError">LibLoading<wbr>Error</a></div><div class="desc docblock-short">Errors.</div></li></ul></section></div></main></body></html>