Skip to content

Instantly share code, notes, and snippets.

@crabtw
Created October 1, 2013 14:37
Show Gist options
  • Save crabtw/6779520 to your computer and use it in GitHub Desktop.
Save crabtw/6779520 to your computer and use it in GitHub Desktop.
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
struct CXCursor {
unsigned kind;
int xdata;
void *data[3];
};
struct CXCursor mk_cxcursor(void) {
struct CXCursor x = {1, 2, {(void*)3, (void*)4, (void*)5}};
return x;
}
typedef unsigned (*Visitor)(struct CXCursor c1, struct CXCursor c2, void *data);
unsigned visit_children(struct CXCursor c, Visitor f, void *data) {
assert(c.kind == 6);
assert(c.xdata == 7);
assert((uintptr_t)c.data[0] == 8);
assert((uintptr_t)c.data[1] == 9);
assert((uintptr_t)c.data[2] == 10);
assert((uintptr_t)data == 0x12345678);
struct CXCursor a = {11, 12, {(void*)13, (void*)14, (void*)15}};
struct CXCursor b = {16, 17, {(void*)18, (void*)19, (void*)20}};
unsigned r = f(a, b, (void*)0x90abcdef);
assert(r == 0x11111111);
return 0xffffffff;
}
RUSTC = rustc
CC = gcc
AR = ar
test: test.rs ffi.o
$(RUSTC) $< -L . -o $@
ffi.o: ffi.c
$(CC) -fPIC -c $< -o $@
clean:
$(RM) -f test ffi.o
.PHONY: clean
use std::libc::*;
pub struct CXCursor {
kind: c_uint,
xdata: c_int,
data: [*c_void, ..3u],
}
type Visitor = extern "C" fn(a: CXCursor, b: CXCursor, x: *c_void) -> c_uint;
#[link_args="ffi.o"]
extern "C" {
pub fn mk_cxcursor() -> CXCursor;
pub fn visit_children(c: CXCursor, f: Visitor, x: *c_void) -> c_uint;
}
extern fn cb(a: CXCursor, b: CXCursor, x: *c_void) -> c_uint {
assert!(a.kind == 11);
assert!(a.xdata == 12);
assert!(a.data[0] as c_uint == 13);
assert!(a.data[1] as c_uint == 14);
assert!(a.data[2] as c_uint == 15);
assert!(b.kind == 16);
assert!(b.xdata == 17);
assert!(b.data[0] as c_uint == 18);
assert!(b.data[1] as c_uint == 19);
assert!(b.data[2] as c_uint == 20);
assert!(x as c_uint == 0x90abcdef);
return 0x11111111;
}
#[fixed_stack_segment]
fn main() {
unsafe {
let c = mk_cxcursor();
assert!(c.kind == 1);
assert!(c.xdata == 2);
assert!(c.data[0] as c_uint == 3);
assert!(c.data[1] as c_uint == 4);
assert!(c.data[2] as c_uint == 5);
let c = CXCursor {
kind: 6,
xdata: 7,
data: [8 as *c_void, 9 as *c_void, 10 as *c_void]
};
let r = visit_children(c, cb, 0x12345678 as *c_void);
assert!(r == 0xffffffff);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment