Re: [rust-dev] Calling back into Rust from C code

2013-05-13 Thread Skirmantas Kligys
On Sun, May 12, 2013 at 3:23 AM, Florian Weimer  wrote:
> * Skirmantas Kligys:
>
>> 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:
>
> It's probably better to avoid calling back into Rust, storing events
> in a buffer in C callbacks.

Florian,

Any reasons why?  Stack overflows?

I now have two working approaches:

1. Store Rust callbacks in a struct, pass it through expat as
user_data: *c_void, cast it back into a struct in a C callback, call
the Rust callback.

2. Create a port/chan pair, pass the chan through expat as user_data:
*c_void, cast it back into chan in a C callback, use it to send
XmlEvent enum variants; a child task listens on the port and does the
processing.

The second approach seems more "rusty" and probably will load two
cores unlike the first.

Both approaches pass data around as *c_void, which makes me a bit
nervous, but I just don't see any other way to pass typed pointers
into a C callback.  Let me know if I am missing something.

Thanks.
Skirmantas Kligys
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Calling back into Rust from C code

2013-05-13 Thread Brian Anderson

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
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Calling back into Rust from C code

2013-05-12 Thread Florian Weimer
* Skirmantas Kligys:

> 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:

It's probably better to avoid calling back into Rust, storing events
in a buffer in C callbacks.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Calling back into Rust from C code

2013-05-12 Thread Matthieu Monrocq
As the error implies, the function type that you try to pass as a callback
is incorrect.

The problem is that because the callback is called from C it ought to be
"compatible" with C, thus the "extern" bit.

Rather than defining an anonymous function, you need to write an "extern
fn" function (with a name), so that the function (at low-level) have a
compatible ABI with C.

-- Matthieu


On Sat, May 11, 2013 at 3:04 AM, Skirmantas Kligys <
skirmantas.kli...@gmail.com> 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?
>
> Thanks.
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Calling back into Rust from C code

2013-05-11 Thread Skirmantas Kligys
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?

Thanks.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev