如果我有以下两组代码,我如何将它们粘合在一起?
void
c_function(void *ptr) {
int i;
for (i = 0; i < 10; i++) {
printf("%p", ptr[i]);
}
return;
}
def python_routine(y):
x = []
for e in y:
x.append(e)
Run Code Online (Sandbox Code Playgroud)
如何在x中使用连续的元素列表调用c_function?我试图将x转换为c_void_p,但这不起作用.
我也试过用类似的东西
x = c_void_p * 10
for e in y:
x[i] = e
Run Code Online (Sandbox Code Playgroud)
但是这会出现语法错误.
C代码显然需要数组的地址.我如何实现这一目标?
我对Rust很新.我如何String从可以在Python中使用的Rust函数返回一个?
这是我的Rust实现:
use std::ffi::CString;
#[no_mangle]
pub extern fn query() -> CString {
let s = CString::new("Hello!").unwrap();
return s;
}
Run Code Online (Sandbox Code Playgroud)
以及调用它的Python代码:
from ctypes import cdll, c_char_p
lib = cdll.LoadLibrary("target/release/libtest.so")
result = lib.query()
print(c_char_p(result).value)
Run Code Online (Sandbox Code Playgroud)
它运行时出现分段错误.
编辑:使用下面的Vladimir Matveev的Rust代码,我能够使用我的python代码的更改:
from ctypes import *
lib = cdll.LoadLibrary("target/release/libtest.so")
lib.query.restype = c_char_p
result = lib.query()
print cast(result, c_char_p).value
lib.free_query(result)
Run Code Online (Sandbox Code Playgroud) 根据这些 答案,我现在定义了一个Rust 1.0函数,如下所示,以便可以使用Python从Python调用ctypes:
use std::vec;
extern crate libc;
use libc::{c_int, c_float, size_t};
use std::slice;
#[no_mangle]
pub extern fn convert_vec(input_lon: *const c_float,
lon_size: size_t,
input_lat: *const c_float,
lat_size: size_t) -> Vec<(i32, i32)> {
let input_lon = unsafe {
slice::from_raw_parts(input_lon, lon_size as usize)
};
let input_lat = unsafe {
slice::from_raw_parts(input_lat, lat_size as usize)
};
let combined: Vec<(i32, i32)> = input_lon
.iter()
.zip(input_lat.iter())
.map(|each| convert(*each.0, *each.1))
.collect();
return combined
}
Run Code Online (Sandbox Code Playgroud)
我正在设置Python部分:
from ctypes import *
class Int32_2(Structure):
_fields_ = …Run Code Online (Sandbox Code Playgroud) 我现在已经学习Rust大约两个星期了,今天我进入了它的FFI.我使用Python来使用Rust,使用ctypes和libc.我通过整数,字符串甚至学会传递整数列表(感谢这个精彩的答案).
然后,我尝试传递一个字符串列表(按照该答案背后的推理),但我失败了,因为我无法获得领先.在Python中,我有类似的东西来传递字符串数组.
def testRust():
lib = ctypes.cdll.LoadLibrary(rustLib)
list_to_send = ['blah', 'blah', 'blah', 'blah']
c_array = (ctypes.c_char_p * len(list_to_send))()
lib.get_strings(c_array, len(list_to_send))
Run Code Online (Sandbox Code Playgroud)
在Rust中,我认为应该有一些东西(比如a STRING_RECEIVER)来收集传入的字符串,但我找不到一个.
#![feature(libc)]
extern crate libc;
use std::slice;
use libc::{size_t, STRING_RECEIVER};
#[no_mangle]
pub extern fn get_strings(array: *const STRING_RECEIVER, length: size_t) {
let values = unsafe { slice::from_raw_parts(array, length as usize) };
println!("{:?}", values);
}
Run Code Online (Sandbox Code Playgroud)
有没有其他方法来实现这一目标?
我有一个Rust库需要通过ctypes模块导入到Python中.我的目标是使用带有Vec<T>/ i32作为参数的Rust函数并从Python返回这些类型.目前,我可以将整数传递给Rust函数,并让它们返回列表/整数.这是当前的代码:
蟒蛇:
import ctypes
from ctypes import cdll
class List_4(ctypes.Structure):
_fields_ = [("array", ctypes.ARRAY(ctypes.c_int32, 4))]
rust = cdll.LoadLibrary("target/debug/py_link.dll")
rust.function_vec.restype = List_4
foobar = rust.function_i32(5)
barbaz = rust.function_vec([1, 2, 3, 4]) # Throws error: Don't know how to convert parameter
print foobar
print barbaz
Run Code Online (Sandbox Code Playgroud)
锈:
#[repr(C)]
pub struct List_4 {
array: [i32; 4]
}
#[no_mangle]
pub extern fn function_i32(number: i32) -> i32 {
number
}
#[no_mangle]
pub extern fn function_vec(list: List_4) -> List_4 {
List_4 { array: …Run Code Online (Sandbox Code Playgroud)