fixed by-val from rust->c, use ++ sigil in native fn sig <-- NEVAR FORGET

have to use ++ sigil in rust-side extern fn decls in order to have rust
actually copy the struct, by value, onto the C stack. gotcha, indeed.

also adding a helper method to verify/remind how to pass a struct by-val
into C... check out the rust fn sig for rust_uv_ip4_test_verify_port_val()
for more infos
This commit is contained in:
Jeff Olson 2012-03-22 21:15:39 -07:00 committed by Brian Anderson
parent 43c82bdb45
commit e5ccc76bc4
2 changed files with 43 additions and 20 deletions

View file

@ -217,17 +217,15 @@ fn gen_stub_uv_write_t() -> uv_write_t {
ret { loop_handle: ptr::null() };
}
// not going to use this type, for now, because of
// github issue #1402
// unix size: 16
#[cfg(target_os = "linux")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
type sockaddr_in = {
sin_family: u16,
sin_port: u16,
sin_addr: u32, // in_addr: this is an opaque, per-platform struct
sin_zero: *u8
mut sin_family: u16,
mut sin_port: u16,
mut sin_addr: u32, // in_addr: this is an opaque, per-platform struct
mut sin_zero: (u8, u8, u8, u8, u8, u8, u8, u8)
};
// unix size: 28 .. make due w/ 32
@ -275,11 +273,14 @@ native mod rustrt {
fn rust_uv_buf_init(base: *u8, len: libc::size_t)
-> *libc::c_void;
fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t;
fn rust_uv_ip4_test_verify_port_val(++addr: sockaddr_in,
expected: libc::c_uint)
-> bool;
fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int)
-> sockaddr_in;
fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
tcp_handle_ptr: *uv_tcp_t,
addr: *libc::c_void,
++addr: sockaddr_in,
after_cb: *u8) -> libc::c_int;
fn rust_uv_write(req: *libc::c_void, stream: *libc::c_void,
buf_in: **libc::c_void, buf_cnt: libc::c_int,
@ -329,9 +330,10 @@ mod direct {
}
unsafe fn tcp_connect(connect_ptr: *uv_connect_t,
tcp_handle_ptr: *uv_tcp_t,
address: *libc::c_void,
address: sockaddr_in,
after_connect_cb: *u8)
-> libc::c_int {
io::println(#fmt("before native tcp_connect -- addr port: %u", address.sin_port as uint));
ret rustrt::rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr,
address, after_connect_cb);
}
@ -380,15 +382,15 @@ mod direct {
unsafe fn buf_init(input: *u8, len: uint) -> *libc::c_void {
ret rustrt::rust_uv_buf_init(input, len);
}
// TODO: see github issue #1402
unsafe fn ip4_addr(ip: str, port: libc::c_int)
unsafe fn ip4_addr(ip: str, port: int)
-> sockaddr_in {
let mut addr_vec = str::bytes(ip);
addr_vec += [0u8]; // add null terminator
let addr_vec_ptr = vec::unsafe::to_ptr(addr_vec);
let ip_back = str::from_bytes(addr_vec);
io::println(#fmt("vec val: '%s' length: %u",ip_back, vec::len(addr_vec)));
ret rustrt::rust_uv_ip4_addr(addr_vec_ptr, port);
ret rustrt::rust_uv_ip4_addr(addr_vec_ptr,
port as libc::c_int);
}
// this is lame.
// TODO: see github issue #1402
@ -1032,11 +1034,11 @@ fn impl_uv_tcp_request() unsafe {
io::println("sucessful tcp_init_result");
io::println("building addr...");
let addr_val = direct::ip4_addr("173.194.33.40", 80i32);
let addr = direct::ip4_addr("173.194.33.40", 80);
io::println(#fmt("after build addr in rust. port: %u",
addr_val.sin_port as uint));
let addr: *libc::c_void = ptr::addr_of(addr_val) as
*libc::c_void;
addr.sin_port as uint));
//let addr: *libc::c_void = ptr::addr_of(addr_val) as
// *libc::c_void;
// this should set up the connection request..
let tcp_connect_result = direct::tcp_connect(
@ -1128,3 +1130,17 @@ fn test_uv_struct_size_sockaddr_in() {
io::println(output);
assert native_handle_size as uint == rust_handle_size;
}
fn impl_uv_byval_test() unsafe {
let addr = direct::ip4_addr("173.194.33.111", 80);
io::println(#fmt("after build addr in rust. port: %u",
addr.sin_port as uint));
assert rustrt::rust_uv_ip4_test_verify_port_val(addr,
addr.sin_port as libc::c_uint);
io::println(#fmt("after build addr in rust. port: %u",
addr.sin_port as uint));
}
#[test]
fn test_uv_ip4_byval_passing_test() {
impl_uv_byval_test();
}

View file

@ -287,12 +287,12 @@ rust_uv_last_error(uv_loop_t* loop) {
extern "C" int
rust_uv_tcp_connect(uv_connect_t* connect_ptr,
uv_tcp_t* tcp_ptr,
void* addr_ptr,
struct sockaddr_in addr,
uv_connect_cb cb) {
//return uv_tcp_connect(connect_ptr, tcp_ptr, addr, cb);
printf("inside rust_uv_tcp_connect\n");
sockaddr_in addr_tmp = *((sockaddr_in*)addr_ptr);
sockaddr_in addr = addr_tmp;
//sockaddr_in addr_tmp = *((sockaddr_in*)addr_ptr);
//sockaddr_in addr = addr_tmp;
printf("before tcp_connect .. port: %d\n", addr.sin_port);
int result = uv_tcp_connect(connect_ptr, tcp_ptr, addr, cb);
printf ("leaving rust_uv_tcp_connect.. and result: %d\n",
@ -313,10 +313,17 @@ rust_uv_write(uv_write_t* req, uv_stream_t* handle,
return uv_write(req, handle, buf_vals, buf_cnt, cb);
}
extern "C" sockaddr_in
extern "C" struct sockaddr_in
rust_uv_ip4_addr(const char* ip, int port) {
printf("before creating addr_ptr.. ip %s port %d\n", ip, port);
sockaddr_in addr = uv_ip4_addr("173.194.33.40", 80);
struct sockaddr_in addr = uv_ip4_addr(ip, port);
printf("after creating .. port: %d\n", addr.sin_port);
return addr;
}
extern "C" bool
rust_uv_ip4_test_verify_port_val(struct sockaddr_in addr,
unsigned int expected) {
printf("inside c++ ip4_test .. port: %u\n", addr.sin_port);
return addr.sin_port == expected;
}