如何在 Rust 和 Python 之间传递指针?
How can a pointer be passed between Rust and Python?
我正在尝试用 Rust 编写一个库,我可以从 Python 代码中调用它。我希望能够将一个 void 指针传回 Python,这样我就可以在 Rust 调用之间保持状态。但是,当我再次尝试访问指针时,我在 Rust 中遇到了段错误。
完整代码示例和崩溃报告:https://gist.github.com/robyoung/3644f13a05c95cb1b947
密码
#![feature(libc)]
#![feature(alloc)]
extern crate libc;
use std::boxed;
pub struct Point {
x: i64,
y: i32,
}
#[no_mangle]
pub extern "C" fn start_state() -> *mut Point {
let point = Box::new(Point{x: 0, y: 10});
let raw = unsafe { boxed::into_raw(point) };
println!("{:?}", raw);
raw
}
#[no_mangle]
pub extern "C" fn continue_state(point: *mut Point) -> i32 {
println!("{:?}", point);
let p = unsafe { Box::from_raw(point) };
println!("{} {}", p.x, p.y);
0
}
import ctypes
lib = ctypes.cdll.LoadLibrary('target/libpytesttype.so')
lib.start_state.restype = ctypes.c_void_p
pointer = lib.start_state()
print("{:x}".format(pointer))
lib.continue_state(pointer)
输出
0xdc24000
10dc24000
0xdc24000
[1] 64006 segmentation fault python src/main.py
我做错了什么?
:
On the Python side, you're missing lib.continue_state.argtypes = (ctypes.c_void_p,). Without defining the parameter as a pointer, ctypes uses the default conversion for a Python integer, which truncates the value to 32-bit, e.g. 0x0dc24000. If you're lucky accessing that address triggers a segfault immediately.
我的输出(带有我自己的填充)是:
0x103424000
103424000
0x 3424000
所以指针的 Debug
格式化程序应该没问题。不确定为什么你的输出不同。
添加后
lib.continue_state.argtypes = (ctypes.c_void_p,)
程序运行就好了。
我正在尝试用 Rust 编写一个库,我可以从 Python 代码中调用它。我希望能够将一个 void 指针传回 Python,这样我就可以在 Rust 调用之间保持状态。但是,当我再次尝试访问指针时,我在 Rust 中遇到了段错误。
完整代码示例和崩溃报告:https://gist.github.com/robyoung/3644f13a05c95cb1b947
密码
#![feature(libc)]
#![feature(alloc)]
extern crate libc;
use std::boxed;
pub struct Point {
x: i64,
y: i32,
}
#[no_mangle]
pub extern "C" fn start_state() -> *mut Point {
let point = Box::new(Point{x: 0, y: 10});
let raw = unsafe { boxed::into_raw(point) };
println!("{:?}", raw);
raw
}
#[no_mangle]
pub extern "C" fn continue_state(point: *mut Point) -> i32 {
println!("{:?}", point);
let p = unsafe { Box::from_raw(point) };
println!("{} {}", p.x, p.y);
0
}
import ctypes
lib = ctypes.cdll.LoadLibrary('target/libpytesttype.so')
lib.start_state.restype = ctypes.c_void_p
pointer = lib.start_state()
print("{:x}".format(pointer))
lib.continue_state(pointer)
输出
0xdc24000
10dc24000
0xdc24000
[1] 64006 segmentation fault python src/main.py
我做错了什么?
On the Python side, you're missing lib.continue_state.argtypes = (ctypes.c_void_p,). Without defining the parameter as a pointer, ctypes uses the default conversion for a Python integer, which truncates the value to 32-bit, e.g. 0x0dc24000. If you're lucky accessing that address triggers a segfault immediately.
我的输出(带有我自己的填充)是:
0x103424000
103424000
0x 3424000
所以指针的 Debug
格式化程序应该没问题。不确定为什么你的输出不同。
添加后
lib.continue_state.argtypes = (ctypes.c_void_p,)
程序运行就好了。