├── .gitignore ├── rlib.h ├── cytest.pyx ├── src └── lib.rs ├── Cargo.toml ├── setup.py └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | *.swp 4 | *.swo 5 | *.so 6 | cytest.c 7 | build/ 8 | -------------------------------------------------------------------------------- /rlib.h: -------------------------------------------------------------------------------- 1 | #ifndef RLIB_H 2 | #define RLIB_H 3 | 4 | double rust_double(double x); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /cytest.pyx: -------------------------------------------------------------------------------- 1 | cdef extern from "rlib.h": 2 | double rust_double(double x) 3 | 4 | def call_rust_double(double x): 5 | return rust_double(x) 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #[no_mangle] 2 | pub extern fn rust_double(x: f64) -> f64 { 3 | x * 2.0 4 | } 5 | 6 | #[test] 7 | fn it_works() { 8 | assert!(rust_double(3.0) == 6.0) 9 | } 10 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustcython_test" 3 | version = "0.1.0" 4 | authors = ["Joshua L. Adelman "] 5 | 6 | [lib] 7 | name = "rustcython_test" 8 | crate-type = ["dylib"] 9 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, Extension, find_packages 2 | 3 | from Cython.Build import cythonize 4 | from Cython.Distutils import build_ext 5 | 6 | ext = Extension('cytest', 7 | sources=['cytest.pyx'], 8 | libraries=['rustcython_test',], 9 | library_dirs=['target/release',], 10 | include_dirs=['.',] 11 | ) 12 | 13 | extensions = [ext,] 14 | 15 | setup( 16 | name = "cytest", 17 | ext_modules = cythonize(extensions), 18 | cmdclass={'build_ext': build_ext}, 19 | ) 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rust-cython-test 2 | A rudimentary example of calling rust from cython 3 | 4 | I've seen a number of examples of calling [Rust](http://www.rust-lang.org/) from python, including Dan Callahad's [talk 5 | at PyCon](https://github.com/callahad/pycon2015-rust), this example from [J. Clifford Dyer](http://harkablog.com/calling-rust-from-c-and-python.html) 6 | as well as in the official [Rust book](https://doc.rust-lang.org/nightly/book/rust-inside-other-languages.html). All of the examples 7 | have used either the [ctypes](https://docs.python.org/2/library/ctypes.html) built-in module or [CFFI](http://cffi.readthedocs.org/). 8 | 9 | Here is a simple example of calling a function defined in rust that doubles a `double` from within [Cython](http://cython.org/). 10 | The example basically relies on the formalism that one would use to call Rust from C. This involves writing a `.h` header file 11 | and linking to the dynamic library generated by rust via the `setup.py` file. 12 | 13 | Basic instructions for running the example: 14 | 15 | ``` 16 | cargo build --release 17 | python setup.py build_ext --inplace 18 | ``` 19 | 20 | Then launching IPython: 21 | 22 | ```python 23 | In [1]: import cytest 24 | 25 | In [2]: cytest.call_rust_double(10.0) 26 | Out[2]: 20.0 27 | ``` 28 | 29 | This example is obviously not very useful, but I wanted to demonstrate the capability. 30 | --------------------------------------------------------------------------------