ffi

Passing a list of strings from Python to Rust

给你一囗甜甜゛ 提交于 2019-12-04 18:37:17
问题 I've been learning Rust for about two weeks now and today, I got into its FFI. I used Python to play with Rust, using ctypes and libc. I passed integers, strings and even learned to pass a list of integers (thanks to this wonderful answer). Then, I tried to pass a list of strings (following the reasoning behind the that answer), but I failed, as I couldn't get a lead on it. In Python, I have something like this to pass the array of strings. def testRust(): lib = ctypes.cdll.LoadLibrary

unsafePerformIO and FFI library initialization

孤人 提交于 2019-12-04 17:37:16
问题 I'm creating an FFI module to a library in C which wants a 1-time, non-reentrant function to be called before anything else is. This call is idempotent, but stateful, so I could just call it in every Haskell call. But it's slow and due to non-reentrancy it could cause conflicts. So is this the right time to use unsafePerformIO? I could wrap a Bool in an unsafe IORef or MVar to make these initialization calls idempotent by ignoring subsequent calls (calls where the global, hidden IORef state

Using higher-order Haskell types in C#

放肆的年华 提交于 2019-12-04 16:22:21
问题 How can I use and call Haskell functions with higher-order type signatures from C# (DLLImport), like... double :: (Int -> Int) -> Int -> Int -- higher order function typeClassFunc :: ... -> Maybe Int -- type classes data MyData = Foo | Bar -- user data type dataFunc :: ... -> MyData What are the corresponding type signature in C#? [DllImport ("libHSDLLTest")] private static extern ??? foo( ??? ); Additionally (because it may be easier): How can I use "unknown" Haskell types within C#, so I

C library freeing a pointer coming from Rust

﹥>﹥吖頭↗ 提交于 2019-12-04 12:38:46
I want to do Rust bindings to a C library which requires a callback, and this callback must return a C-style char* pointer to the C library which will then free it. The callback must be in some sense exposed to the user of my library (probably using closures), and I want to provide a Rust interface as convenient as possible (meaning accepting a String output if possible). However, the C library complains when trying to free() a pointer coming from memory allocated by Rust, probably because Rust uses jemalloc and the C library uses malloc. So currently I can see two workarounds using libc:

Is it possible to use Fiddle to pass or return a struct to native code?

微笑、不失礼 提交于 2019-12-04 10:01:13
问题 I would like to use Fiddle to access a native library compiled from Rust code. The C representation of the struct is very simple, it is just a pointer and a length: typedef struct { char *data; size_t len; } my_thing_t; // Example function that somehow accepts a struct void accepts_a_struct(my_thing_t thing); // Example function that somehow returns a struct my_thing_t returns_a_struct(void); However, all examples I can find accept or return pointers to structs, and not the structs themselves

How do I return an vector of dynamic length in a pub extern “C” fn?

*爱你&永不变心* 提交于 2019-12-04 07:39:10
I want to return a vector in a pub extern "C" fn . Since a vector has an arbitrary length, I guess I need to return a struct with the pointer to the vector, and the number of elements in the vector My current code is: extern crate libc; use self::libc::{size_t, int32_t, int64_t}; // struct to represent an array and its size #[repr(C)] pub struct array_and_size { values: int64_t, // this is probably not how you denote a pointer, right? size: int32_t, } // The vector I want to return the address of is already in a Boxed struct, // which I have a pointer to, so I guess the vector is on the heap

Can a struct containing a raw pointer implement Send and be FFI safe?

醉酒当歌 提交于 2019-12-04 06:31:45
I have a scenario where Rust will call C to malloc a buffer and stash the resulting pointer into a struct. Later on, the struct will be moved to a thread and passed to a C function which mutates it. The naive approach to my problem looks like this ( playground ): extern crate libc; use libc::{c_void, malloc, size_t}; use std::thread; const INITIAL_CAPACITY: size_t = 8; extern "C" { fn mutate(s: *mut Storage); } #[repr(C)] struct Storage { #[allow(dead_code)] buf: *mut c_void, capacity: usize, } fn main() { let buf = unsafe { malloc(INITIAL_CAPACITY) }; let mut s = Storage { buf: buf, capacity:

Segmentation fault when calling a Rust lib with Ruby FFI

风格不统一 提交于 2019-12-04 04:50:36
I want to pass in a String to a Rust lib, but it always throws a segmentation fault. Here's the code: // lib.rs #[no_mangle] pub extern fn process(foo: String) -> String { foo } And the Ruby file: # embed.rb require 'ffi' module Hello extend FFI::Library ffi_lib 'target/release/libembed.dylib' attach_function :process, [ :string ], :string end puts Hello.process("foo") DK. Disclaimer : I've never used Ruby-FFI before; I'm going on what I can find in the documentation. According to the Ruby-FFI wiki page on types , :string is equivalent to a NUL-terminated C string. This is not the same as a

How can I index C arrays in Rust?

故事扮演 提交于 2019-12-04 04:44:00
问题 I have a C function returning a pointer: type MYSQL_RES_REF = *mut c_void; type MYSQL_ROW = *const *const c_char; #[no_mangle] extern "C" { fn mysql_fetch_row(res: MYSQL_RES_REF) -> MYSQL_ROW; } let pointer = mysql_fetch_row(self.res); let row_p = match pointer { p if p == (0 as *const *const c_char) => panic!(), p => p, }; let field: &[u8] = unsafe { ffi::c_str_to_bytes(row_p[i]) }; but attempting to index it (the last line) results in an error: error: cannot index a value of type `*const

How to represent a pointer to an array in Rust for C

℡╲_俬逩灬. 提交于 2019-12-04 03:43:55
问题 I need an extern "C" FFI function in Rust and want to accept an array of fixed size. The C code passes something like: // C code extern int(*)[4] call_rust_funct(unsigned char (*)[3]); .... unsigned char a[] = { 11, 255, 212 }; int(*p)[4] = call_rust_funct(&a); How do I write my Rust function for it ? // Pseudo code - DOESN'T COMPILE pub unsafe extern "C" fn call_rust_funct(_p: *mut u8[3]) -> *mut i32[4] { Box::into_raw(Box::new([99i32; 4])) } 回答1: You just need to use Rust's syntax for fixed