On 05/10/2013 06:04 PM, Skirmantas Kligys wrote:
I am trying to write a native wrapper for

https://github.com/pascalj/rust-expat

(BTW, if there is a native Rust XML parser, I am interested to hear
about it, did not find it).  I have trouble calling back into Rust
from C code:

fn set_element_handlers(parser: expat::XML_Parser, start_handler:
&fn(tag: &str, attrs: &[@str]), end_handler: &fn(tag: &str)) {
   let start_cb = |_user_data: *c_void, c_name: *c_char, _c_attrs: **c_char| {
     unsafe {
       let name = str::raw::from_c_str(c_name);
       start_handler(name, []);
     }
   };

   let end_cb = |_user_data: *c_void, c_name: *c_char| {
     unsafe {
       let name = str::raw::from_c_str(c_name);
       end_handler(name);
     }
   };

   expat::XML_SetElementHandler(parser, start_cb, end_cb);
}

This says that it saw &fn... instead of expected extern fn for the
second and third parameter.  Any ideas how to do this?


You need a function type that is compatible with C. Here `start_cb` is a Rust closure, using the Rust ABI, but you need it to be a C function pointer. It should be defined more like

extern fn start_cb(user_data: *c_void, c_name: *c_char, c_attrs: **c_char) { ... }

The `extern` says that it uses a foreign ABI, C by default. You can take a value to it like

    let start: *u8 = start_cb;

Note that the extern fn has type *u8. This is a temporary hack. Eventually it will have type `extern "C" fn(...)`.

Then your XML_SetElementHandler can be defined like `fn XML_SetELementHandler(parser: Parser, start_cb: *u8, end_cb: *u8)`.

Good luck.

-Brian
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to