Improve pyo3-ffi example

This commit is contained in:
mejrs 2022-08-22 22:27:05 +02:00
parent 3845e3fe33
commit 5b845d3b1a

View file

@ -88,64 +88,40 @@
//!
//! use pyo3_ffi::*;
//!
//! #[allow(non_snake_case)]
//! #[no_mangle]
//! pub unsafe extern "C" fn PyInit_string_sum() -> *mut PyObject {
//! let init = PyModuleDef {
//! static mut MODULE_DEF: PyModuleDef = PyModuleDef {
//! m_base: PyModuleDef_HEAD_INIT,
//! m_name: "string_sum\0".as_ptr() as *const c_char,
//! m_doc: std::ptr::null(),
//! m_name: "string_sum\0".as_ptr().cast::<c_char>(),
//! m_doc: "A Python module written in Rust.\0"
//! .as_ptr()
//! .cast::<c_char>(),
//! m_size: 0,
//! m_methods: std::ptr::null_mut(),
//! m_methods: unsafe { METHODS.as_mut_ptr().cast() },
//! m_slots: std::ptr::null_mut(),
//! m_traverse: None,
//! m_clear: None,
//! m_free: None,
//! };
//!
//! let mptr = PyModule_Create(Box::into_raw(Box::new(init)));
//! let version = env!("CARGO_PKG_VERSION");
//! PyModule_AddObject(
//! mptr,
//! "__version__\0".as_ptr() as *const c_char,
//! PyUnicode_FromStringAndSize(version.as_ptr() as *const c_char, version.len() as isize),
//! );
//!
//! let wrapped_sum_as_string = PyMethodDef {
//! ml_name: "sum_as_string\0".as_ptr() as *const c_char,
//! static mut METHODS: [PyMethodDef; 2] = [
//! PyMethodDef {
//! ml_name: "sum_as_string\0".as_ptr().cast::<c_char>(),
//! ml_meth: PyMethodDefPointer {
//! _PyCFunctionFast: sum_as_string
//! _PyCFunctionFast: sum_as_string,
//! },
//! ml_flags: METH_FASTCALL,
//! ml_doc: "returns the sum of two integers as a string\0".as_ptr() as *const c_char,
//! };
//! ml_doc: "returns the sum of two integers as a string\0"
//! .as_ptr()
//! .cast::<c_char>(),
//! },
//! // A zeroed PyMethodDef to mark the end of the array.
//! PyMethodDef::zeroed()
//! ];
//!
//! // PyModule_AddObject can technically fail.
//! // For more involved applications error checking may be necessary
//! PyModule_AddObject(
//! mptr,
//! "sum_as_string\0".as_ptr() as *const c_char,
//! PyCFunction_NewEx(
//! Box::into_raw(Box::new(wrapped_sum_as_string)),
//! std::ptr::null_mut(),
//! PyUnicode_InternFromString("string_sum\0".as_ptr() as *const c_char),
//! ),
//! );
//!
//! let all = ["__all__\0", "__version__\0", "sum_as_string\0"];
//!
//! let pyall = PyTuple_New(all.len() as isize);
//! for (i, obj) in all.iter().enumerate() {
//! PyTuple_SET_ITEM(
//! pyall,
//! i as isize,
//! PyUnicode_InternFromString(obj.as_ptr() as *const c_char),
//! )
//! }
//!
//! PyModule_AddObject(mptr, "__all__\0".as_ptr() as *const c_char, pyall);
//!
//! mptr
//! // The module initialization function, which must be named `PyInit_<your_module>`.
//! #[allow(non_snake_case)]
//! #[no_mangle]
//! pub unsafe extern "C" fn PyInit_string_sum() -> *mut PyObject {
//! PyModule_Create(ptr::addr_of_mut!(MODULE_DEF))
//! }
//!
//! pub unsafe extern "C" fn sum_as_string(
@ -154,43 +130,61 @@
//! nargs: Py_ssize_t,
//! ) -> *mut PyObject {
//! if nargs != 2 {
//! return raise_type_error("sum_as_string() expected 2 positional arguments");
//! PyErr_SetString(
//! PyExc_TypeError,
//! "sum_as_string() expected 2 positional arguments\0"
//! .as_ptr()
//! .cast::<c_char>(),
//! );
//! return std::ptr::null_mut();
//! }
//!
//! let arg1 = *args;
//! if PyLong_Check(arg1) == 0 {
//! return raise_type_error("sum_as_string() expected an int for positional argument 1");
//! PyErr_SetString(
//! PyExc_TypeError,
//! "sum_as_string() expected an int for positional argument 1\0"
//! .as_ptr()
//! .cast::<c_char>(),
//! );
//! return std::ptr::null_mut();
//! }
//!
//! let arg1 = PyLong_AsLong(arg1);
//! if !PyErr_Occurred().is_null() {
//! return ptr::null_mut()
//! return ptr::null_mut();
//! }
//!
//! let arg2 = *args.add(1);
//! if PyLong_Check(arg2) == 0 {
//! return raise_type_error("sum_as_string() expected an int for positional argument 2");
//! PyErr_SetString(
//! PyExc_TypeError,
//! "sum_as_string() expected an int for positional argument 2\0"
//! .as_ptr()
//! .cast::<c_char>(),
//! );
//! return std::ptr::null_mut();
//! }
//!
//! let arg2 = PyLong_AsLong(arg2);
//! if !PyErr_Occurred().is_null() {
//! return ptr::null_mut()
//! }
//! let res = (arg1 + arg2).to_string();
//! PyUnicode_FromStringAndSize(res.as_ptr() as *const c_char, res.len() as isize)
//! return ptr::null_mut();
//! }
//!
//! #[cold]
//! #[inline(never)]
//! fn raise_type_error(msg: &str) -> *mut PyObject {
//! unsafe {
//! let err_msg =
//! PyUnicode_FromStringAndSize(msg.as_ptr() as *const c_char, msg.len() as isize);
//! PyErr_SetObject(PyExc_TypeError, err_msg);
//! Py_DECREF(err_msg);
//! };
//! match arg1.checked_add(arg2) {
//! Some(sum) => {
//! let string = sum.to_string();
//! PyUnicode_FromStringAndSize(string.as_ptr().cast::<c_char>(), string.len() as isize)
//! }
//! None => {
//! PyErr_SetString(
//! PyExc_OverflowError,
//! "arguments too large to add\0".as_ptr().cast::<c_char>(),
//! );
//! std::ptr::null_mut()
//! }
//! }
//! }
//! ```
//!
//! With those two files in place, now `maturin` needs to be installed. This can be done using