update ffi load impls

This commit is contained in:
llama 2025-11-02 17:57:59 +08:00
parent cd156d8524
commit cea6263688
No known key found for this signature in database
GPG key ID: 0B7543854B9413C3
2 changed files with 40 additions and 18 deletions

View file

@ -23,7 +23,7 @@ impl Drop for PyFfi {
} }
macro_rules! load_sym { macro_rules! load_sym {
($lib:expr, $name:literal) => {{ ($lib:expr, $name:expr) => {{
libc::dlerror(); libc::dlerror();
let sym = libc::dlsym($lib, $name.as_ptr()); let sym = libc::dlsym($lib, $name.as_ptr());
if sym.is_null() { if sym.is_null() {
@ -34,9 +34,16 @@ macro_rules! load_sym {
}}; }};
} }
macro_rules! ffi {
($lib:expr, $exec:expr, $($field:ident),* $(,)?) => {
#[allow(clippy::missing_transmute_annotations)] // they're not missing
PyFfi { exec: $exec, $($field: load_sym!($lib, ::std::ffi::CString::new(stringify!($field)).unwrap()),)* lib: $lib, }
};
}
impl PyFfi { impl PyFfi {
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn load(path: impl AsRef<std::path::Path>) -> Result<Self> { pub fn load(path: impl AsRef<std::path::Path>, exec: CString) -> Result<Self> {
unsafe { unsafe {
libc::dlerror(); libc::dlerror();
let lib = libc::dlopen( let lib = libc::dlopen(
@ -48,14 +55,18 @@ impl PyFfi {
anyhow::bail!("failed to load library: {dlerror_str}"); anyhow::bail!("failed to load library: {dlerror_str}");
} }
#[allow(clippy::missing_transmute_annotations)] // they're not missing Ok(ffi!(
Ok(PyFfi {
Py_InitializeEx: load_sym!(lib, c"Py_InitializeEx"),
Py_IsInitialized: load_sym!(lib, c"Py_IsInitialized"),
PyRun_SimpleString: load_sym!(lib, c"PyRun_SimpleString"),
Py_FinalizeEx: load_sym!(lib, c"Py_FinalizeEx"),
lib, lib,
}) exec,
Py_IsInitialized,
PyRun_SimpleString,
Py_FinalizeEx,
PyConfig_InitPythonConfig,
PyConfig_SetBytesString,
Py_InitializeFromConfig,
PyConfig_SetBytesArgv,
PyStatus_Exception
))
} }
} }
} }

View file

@ -286,7 +286,7 @@ impl Drop for PyFfi {
} }
macro_rules! load_sym { macro_rules! load_sym {
($lib:expr, $name:literal) => { ($lib:expr, $name:expr) => {
std::mem::transmute( std::mem::transmute(
GetProcAddress($lib, PCSTR::from_raw($name.as_ptr().cast())) GetProcAddress($lib, PCSTR::from_raw($name.as_ptr().cast()))
.ok_or_else(|| anyhow!("failed to load {}", $name.to_string_lossy()))?, .ok_or_else(|| anyhow!("failed to load {}", $name.to_string_lossy()))?,
@ -294,9 +294,16 @@ macro_rules! load_sym {
}; };
} }
macro_rules! ffi {
($lib:expr, $exec:expr, $($field:ident),* $(,)?) => {
#[allow(clippy::missing_transmute_annotations)] // they're not missing
PyFfi { exec: $exec, $($field: load_sym!($lib, ::std::ffi::CString::new(stringify!($field)).unwrap()),)* lib: $lib.0, }
};
}
impl PyFfi { impl PyFfi {
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn load(path: impl AsRef<std::path::Path>) -> Result<Self> { pub fn load(path: impl AsRef<std::path::Path>, exec: CString) -> Result<Self> {
unsafe { unsafe {
let wide_filename: Vec<u16> = path let wide_filename: Vec<u16> = path
.as_ref() .as_ref()
@ -311,13 +318,17 @@ impl PyFfi {
LOAD_LIBRARY_FLAGS::default(), LOAD_LIBRARY_FLAGS::default(),
)?; )?;
#[allow(clippy::missing_transmute_annotations)] // they're not missing Ok(ffi! {
Ok(PyFfi { lib,
Py_InitializeEx: load_sym!(lib, c"Py_InitializeEx"), exec,
Py_IsInitialized: load_sym!(lib, c"Py_IsInitialized"), Py_IsInitialized,
PyRun_SimpleString: load_sym!(lib, c"PyRun_SimpleString"), PyRun_SimpleString,
Py_FinalizeEx: load_sym!(lib, c"Py_FinalizeEx"), Py_FinalizeEx,
lib: lib.0, PyConfig_InitPythonConfig,
PyConfig_SetBytesString,
Py_InitializeFromConfig,
PyConfig_SetBytesArgv,
PyStatus_Exception,
}) })
} }
} }