Consider a simple rust class exposed via pyo3 to python
use pyo3::prelude::*;
#[pyclass(name=MyClass)]
pub struct PyMyClass {
// Some fields
}
#[pymethods]
impl PyMyStruct {
#[new]
fn py_new(obj: PyRawObject) {
obj.init({
PyMyStruct {
// ...
}
});
}
}
now there is a function which should be called with two of this structs from python in that manner:
a = MyStruct()
b = MyStruct()
c = foo(a,b)
Therefore one defines
#[pyfunction]
fn foo(a: PyMyStruct, b: PyMyStruct) -> PyResult<PyMyStruct> {
// some high performance logic implemented in rust ...
}
Now the compiler claims PyMyStruct
should implement the trait FromPyObject
:
impl FromPyObject<'_> for PyMyStruct {
fn extract(ob: &'_ PyAny) ->PyResult<Self> {
// I dont know what to do here :(
}
}
But I dont know how to retrieve an instance, pointer or whatever of PyMyStruct
from PyAny
... Can someone help me?
I don't know much about this crate but I think that you should take your objects by reference. Note that they are shared with the rest of the Python interpreter, so you can't actually own them.
That is, just write:
#[pyfunction]
fn foo(a: &PyMyStruct, b: &PyMyStruct) -> PyResult<PyMyStruct> {
// some high performance logic implemented in rust ...
}
Or if you want mutable objects:
#[pyfunction]
fn foo(a: &mut PyMyStruct, b: &mut PyMyStruct) -> PyResult<PyMyStruct> {
// some high performance logic implemented in rust ...
}
This works because there are these impls :
impl<'a, T> FromPyObject<'a> for &'a T where
T: PyTryFrom<'a>
impl<'a, T> FromPyObject<'a> for &'a mut T where
T: PyTryFrom<'a>,
and then this other one :
impl<'v, T> PyTryFrom<'v> for T where
T: PyTypeInfo
What happens if you use the &mut
variant and you pass the same object twice to this function? Well, I'm not sure but skimming the code I guess that you get two &mut
references to the same object, and thus undefined behavior . If I were you, I'd use the non mut
variant and use a RefCell
if you actually want to change the object.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.