Skip to main content

vapoursynth_sys/
vsscript_loader.rs

1use std::sync::atomic::AtomicPtr;
2
3#[cfg(all(unix, feature = "vsscript-r73-compat"))]
4use libloading::os::unix::{RTLD_GLOBAL, RTLD_NOW};
5
6pub const VSSCRIPT_PATH_VARIABLE: &str = "VSSCRIPT_PATH";
7
8pub const VSSCRIPT_LIB_NAMES: &[&str] = if cfg!(target_os = "windows") {
9    &["VSScript.dll"]
10} else if cfg!(target_os = "macos") {
11    &["libvsscript.dylib", "libvapoursynth-script.dylib"]
12} else {
13    &["libvsscript.so", "libvapoursynth-script.so"]
14};
15
16pub struct VSScriptAPILoader {
17    __library: ::libloading::Library,
18    pub getVSScriptAPI: Result<
19        unsafe extern "C" fn(version: ::std::os::raw::c_int) -> *const VSSCRIPTAPI,
20        ::libloading::Error,
21    >,
22
23    /// A cached VSScript API pointer.
24    ///
25    /// Internal convenience cache, shares a lifetime with Library
26    pub RAW_VSSCRIPT_API: AtomicPtr<VSSCRIPTAPI>,
27}
28
29impl VSScriptAPILoader {
30    /// # Safety
31    /// Refer to [`libloading::Library`]
32    pub unsafe fn new<P>(path: P) -> Result<Self, ::libloading::Error>
33    where
34        P: libloading::AsFilename,
35    {
36        unsafe {
37            // Older versions don't seem compatible with default flags on UNIX (RTLD_LOCAL)
38            #[cfg(all(unix, feature = "vsscript-r73-compat"))]
39            let library =
40                ::libloading::os::unix::Library::open(Some(path), RTLD_NOW | RTLD_GLOBAL)?;
41            #[cfg(not(all(unix, feature = "vsscript-r73-compat")))]
42            let library = ::libloading::Library::new(path)?;
43
44            Self::from_library(library)
45        }
46    }
47
48    /// # Safety
49    /// Refer to [`libloading::Library`]
50    pub unsafe fn from_library<L>(library: L) -> Result<Self, ::libloading::Error>
51    where
52        L: Into<::libloading::Library>,
53    {
54        let __library = library.into();
55        let getVSScriptAPI = unsafe { __library.get(b"getVSScriptAPI\0").map(|sym| *sym) };
56
57        Ok(VSScriptAPILoader {
58            __library,
59            getVSScriptAPI,
60            RAW_VSSCRIPT_API: AtomicPtr::new(std::ptr::null_mut()),
61        })
62    }
63
64    /// # Safety
65    pub unsafe fn getVSScriptAPI(&self, version: ::std::os::raw::c_int) -> *const VSSCRIPTAPI {
66        unsafe {
67            (self
68                .getVSScriptAPI
69                .as_ref()
70                .expect("Expected function, got error."))(version)
71        }
72    }
73}