From 0ca1f6ab7be14c638a790a37d733d4e7c086cdcb Mon Sep 17 00:00:00 2001 From: Tim Brooks Date: Thu, 15 Jan 2015 20:45:55 +0000 Subject: [PATCH 1/5] Tidy up Makefile --- .gitignore | 3 +++ Makefile | 32 ++++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index db4561e..39ac521 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# test program +ctest + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/Makefile b/Makefile index 319c98b..43881ab 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,29 @@ -all: lib test +.PHONY: all lib test memcheck clean -lib: - rustc points.rs +OS := $(shell uname) -test: - gcc -o test test.c +ifeq ($(OS),Darwin) + LIB = libpoints.dylib +else + LIB = libpoints.so +endif -memcheck: - valgrind --tool=memcheck --leak-check=full ./test +all: $(LIB) test + +lib: $(LIB) + +$(LIB): points.rs + rustc points.rs + +ctest: test.c $(LIB) + gcc -o ctest test.c -g -ldl + +test: $(LIB) ctest + ./ctest + python load_libpoint.py + +memcheck: ctest + valgrind --tool=memcheck --leak-check=full ./ctest clean: - rm -f libpoints.dylib libpoints.so test + rm -f $(LIB) ctest From be5aa0212db12746697eda47fdd51874b1004f86 Mon Sep 17 00:00:00 2001 From: Tim Brooks Date: Thu, 15 Jan 2015 20:46:59 +0000 Subject: [PATCH 2/5] Update Rust syntax --- points.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/points.rs b/points.rs index 5812694..405d01f 100644 --- a/points.rs +++ b/points.rs @@ -1,34 +1,36 @@ #![crate_type = "dylib"] #![crate_name = "points"] +#![allow(unstable)] // Based on http://blog.skylight.io/bending-the-curve-writing-safe-fast-native-gems-with-rust/ // by Yehuda Katz -use std::num::pow; +use std::num::{Int, Float}; -pub struct Point { x: int, y: int } -struct Line { p1: Point, p2: Point } +#[derive(Copy)] +pub struct Point { x: isize, y: isize } +struct Line { p1: Point, p2: Point } -impl Line { +impl Line { pub fn length(&self) -> f64 { let xdiff = self.p1.x - self.p2.x; let ydiff = self.p1.y - self.p2.y; - ((pow(xdiff, 2) + pow(ydiff, 2)) as f64).sqrt() + ((xdiff.pow(2) + ydiff.pow(2)) as f64).sqrt() } } #[no_mangle] -pub extern "C" fn make_point(x: int, y: int) -> Box { - box Point { x: x, y: y } +pub extern "C" fn make_point(x: isize, y: isize) -> Box { + Box::new(Point{x: x, y: y}) } #[no_mangle] -pub extern "C" fn free_point(p: Box) { +pub extern "C" fn free_point(p: Box) { drop(p); } #[no_mangle] -pub extern "C" fn get_distance(p1: &Point, p2: &Point) -> f64 { - Line { p1: *p1, p2: *p2 }.length() -} \ No newline at end of file +pub extern "C" fn get_distance(p1: Box, p2: Box) -> f64 { + Line{p1: *p1, p2: *p2 }.length() +} From 377eabac9070e638188cffb6576015c989c314fd Mon Sep 17 00:00:00 2001 From: Tim Brooks Date: Thu, 15 Jan 2015 20:47:39 +0000 Subject: [PATCH 3/5] Use shared lib in C test code --- test.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/test.c b/test.c index aa6460c..662953c 100644 --- a/test.c +++ b/test.c @@ -1,25 +1,28 @@ #include #include +#ifdef __APPLE__ +#define LIBEXT "dylib" +#else +#define LIBEXT "so" +#endif - -typedef struct Point* (_make_point)( int x, int y); +typedef struct Point* (_make_point)(int x, int y); typedef struct Point* (_free_point)(struct Point* p); -typedef double (_get_distance)( struct Point* a, struct Point* b); - +typedef double (_get_distance)(struct Point* a, struct Point* b); int main(int argc, char *argv[]) { - void *myso = dlopen("./libpoints.dylib", RTLD_NOW); - + void *myso = dlopen("./libpoints." LIBEXT, RTLD_NOW); + _make_point *make_point = dlsym(myso, "make_point"); _free_point *free_point = dlsym(myso, "free_point"); _get_distance *get_distance = dlsym(myso, "get_distance"); - struct Point* a = make_point(10,10); struct Point* b = make_point(20,20); + double d = get_distance(a,b); printf("distance: %f\n", d); @@ -29,5 +32,4 @@ int main(int argc, char *argv[]) { dlclose(myso); return 0; - -} \ No newline at end of file +} From 9ef56a1f6428c78e586aaa53a5fb35764fb0ba23 Mon Sep 17 00:00:00 2001 From: Tim Brooks Date: Thu, 15 Jan 2015 20:49:13 +0000 Subject: [PATCH 4/5] Fix path to library --- load_libpoint.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/load_libpoint.py b/load_libpoint.py index fec4f89..8b4023c 100644 --- a/load_libpoint.py +++ b/load_libpoint.py @@ -18,9 +18,9 @@ """) if sys.platform == "darwin": - libname = "libpoints.dylib" + libname = "./libpoints.dylib" else: - libname = "libpoints.so" + libname = "./libpoints.so" lib = ffi.dlopen(libname) From 0798745abef5346d9e0fe9e232402636bfbd8d54 Mon Sep 17 00:00:00 2001 From: Tim Brooks Date: Thu, 15 Jan 2015 20:50:45 +0000 Subject: [PATCH 5/5] Spruce up Python syntax --- load_libpoint.py | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) mode change 100644 => 100755 load_libpoint.py diff --git a/load_libpoint.py b/load_libpoint.py old mode 100644 new mode 100755 index 8b4023c..5ae4ba3 --- a/load_libpoint.py +++ b/load_libpoint.py @@ -1,35 +1,41 @@ +#!/usr/bin/env python """ Small example how to load the shared library created with rust in python -by Lutz Paelike +by Lutz Paelike """ +# pylint: disable=invalid-name + +from __future__ import print_function import sys import cffi -ffi=cffi.FFI() +FFI = cffi.FFI() +FFI.cdef(""" + struct Point{ int x,y; }; -ffi.cdef (""" - struct Point { int x,y; }; - struct Point* make_point(int, int); - void free_point(struct Point*); + void free_point(struct Point*); - double get_distance( struct Point*, struct Point*); + double get_distance(struct Point*, struct Point*); """) if sys.platform == "darwin": - libname = "./libpoints.dylib" + LIBNAME = "./libpoints.dylib" else: - libname = "./libpoints.so" - -lib = ffi.dlopen(libname) + LIBNAME = "./libpoints.so" +LIB = FFI.dlopen(LIBNAME) -a = lib.make_point(20,20) -b = lib.make_point(10,10) +def main(): + """Show use of Rust structs and functions""" + a = LIB.make_point(20, 20) + b = LIB.make_point(10, 10) -print "distance : ",lib.get_distance(a,b) + print("distance: {:.8g}".format(LIB.get_distance(a, b))) -lib.free_point(a) -lib.free_point(b) + LIB.free_point(a) + LIB.free_point(b) +if __name__ == '__main__': + main()