Skip to content

Instantly share code, notes, and snippets.

@ChristopherRabotin
Created February 8, 2018 18:07
Show Gist options
  • Save ChristopherRabotin/a824c1d482420036e7915a147d2b5f29 to your computer and use it in GitHub Desktop.
Save ChristopherRabotin/a824c1d482420036e7915a147d2b5f29 to your computer and use it in GitHub Desktop.
Rust Python FFI with Python function defintion called by Rust (broken)

Note: Sorry, this code is incredibly messy. I'm trying to make this work, but it does not yet at all.

Problem

I get a segmentation fault when calling the function passed by reference. Calling the main

Issue

xxx@linux-fkyc:~/Workspace/nyxbin/src> python3 example_build.py 
generating ./_my_example.c
running build_ext
building '_my_example' extension
/usr/bin/gcc -Wno-unused-result -DNDEBUG -fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -g -DOPENSSL_LOAD_CONF -fPIC -I/usr/include/python3.4m -c _my_example.c -o ./_my_example.o
gcc -pthread -shared ./_my_example.o -L/usr/lib64 -lpython3.4m -o ./_my_example.cpython-34m.so

xxx@linux-fkyc:~/Workspace/nyxbin/src> python3 loader.py 
<cffi.api._make_ffi_library.<locals>.FFILibrary object at 0x7f9d4ba509b0> ['dyndisp_negate', 'dyndisp_t2']
t2
t2: 2
Segmentation fault (core dumped)
[package]
name = "nyxbin"
version = "0.1.0"
authors = ["XX <YY@ZZ.com>"]
[dependencies]
nalgebra = "0.14.0"
[lib]
name = "nyxbin"
crate-type = ["dylib"]
from _my_example import ffi
from cffi import FFI
ffibuilder = FFI()
lib = ffibuilder.dlopen("../libnyxbin.so")
# @ffi.callback("int(int, int *)")
# def python_callback(how_many, values):
# print ffi.unpack(values, how_many)
# return 0
#lib.python_callback = python_callback
@ffi.def_extern()
def my_bool_func_py(val):
print("python says {}".format(val))
return val
@ffi.def_extern()
def my_int_func_py():
print("in my_int_func_py")
#print("in my_int_func_py: {}".format(val))
return
# print ("rust: {}".format(lib.dyndisp_negate(True, my_bool_func_py)))
# file "example_build.py"
import cffi
ffibuilder = cffi.FFI()
lib = ffibuilder.dlopen("../libnyxbin.so")
ffibuilder.cdef("""
extern "Python" bool my_bool_func_py(bool);
extern "Python" void my_int_func_py();
""")
ffibuilder.set_source("_my_example", r"""
#include <stdbool.h>
bool dyndisp_negate(bool pyval, bool (*fun)(bool));
int dyndisp_t2(int pyval, void (*fun)());
""")
ffibuilder.compile(verbose=True)
extern crate nalgebra as na;
use na::DVector;
fn demo(t: f64, vec: DVector<f64>) -> DVector<f64> {
t*vec
}
fn prop<F>(func: F) -> DVector<f64> where F:Fn(f64, DVector<f64>) -> DVector<f64>{
// TODO: How to get the current state? In smd, it's part of the integrator
let test = DVector::from_element(2, 2.0);
func(2.0, test)
}
#[no_mangle]
pub extern fn prop_dyndisp(func: &Fn(f64, DVector<f64>) -> DVector<f64>) -> DVector<f64>{
// TODO: How to get the current state? In smd, it's part of the integrator
let test = DVector::from_element(2, 2.0);
func(2.0, test)
}
#[no_mangle]
pub extern fn dyndisp_negate(val:bool, func: &Fn(bool) -> bool) -> bool{
!func(val)
}
#[no_mangle]
pub extern fn dyndisp_t2(val:i32, func: &Fn() -> i32) -> i32{
println!("t2"); // Works
println!("t2: {}", val); // Works with primitive
func(); // Segfaults =(
println!("post");
//2*func(val)
2
}
/*fn main() {
println!("Hello, world!");
println!("{}", prop(demo));
println!("{}", prop_dyndisp(&demo));
}
*/
from cffi import FFI
ffibuilder = FFI()
# ffibuilder.cdef('bool dyndisp_negate(bool pyval, void (*fun));')
ffibuilder.cdef("""
extern "Python" int my_bool_func_py(bool);
bool dyndisp_negate(bool pyval, int (*fun)(bool));
int dyndisp_t2(int pyval, void (*fun)()); // should this be int?
""")
import _my_example
lib = ffibuilder.dlopen("../libnyxbin.so")
print(lib, dir(lib))
# should print 4
print('dyndisp_t2: {}'.format(lib.dyndisp_t2(2, _my_example.lib.my_int_func_py))) # Segfaults =(
print('dyndisp_negate: {}'.format(lib.dyndisp_negate(True, _my_example.lib.my_bool_func_py)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment