Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# test program
ctest

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
32 changes: 24 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
@@ -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
38 changes: 22 additions & 16 deletions load_libpoint.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -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()
24 changes: 13 additions & 11 deletions points.rs
Original file line number Diff line number Diff line change
@@ -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<Point> {
box Point { x: x, y: y }
pub extern "C" fn make_point(x: isize, y: isize) -> Box<Point> {
Box::new(Point{x: x, y: y})
}

#[no_mangle]
pub extern "C" fn free_point(p: Box<Point>) {
pub extern "C" fn free_point(p: Box<Point>) {
drop(p);
}

#[no_mangle]
pub extern "C" fn get_distance(p1: &Point, p2: &Point) -> f64 {
Line { p1: *p1, p2: *p2 }.length()
}
pub extern "C" fn get_distance(p1: Box<Point>, p2: Box<Point>) -> f64 {
Line{p1: *p1, p2: *p2 }.length()
}
20 changes: 11 additions & 9 deletions test.c
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
#include <dlfcn.h>
#include <stdio.h>

#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);

Expand All @@ -29,5 +32,4 @@ int main(int argc, char *argv[]) {
dlclose(myso);

return 0;

}
}