-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Plugins] non static functions cannot be used for plugin ops #5478
Comments
If we really wanted to then we could change the interface to take a trait object: fn register_op(
&mut self,
name: &str,
dispatcher: &dyn Fn(&mut dyn Interface, &[u8], Option<ZeroCopyBuf>) -> Op
) -> OpId; But I'm not really sure that's necessary. The important difference between a TLDR: unless you need to capture variables, this is possible: pub fn wrap_op<D>(d: D) -> fn(&mut dyn Interface, &[u8], Option<ZeroCopyBuf>) -> Op
where
D: Fn(&mut C, &[u8], Option<ZeroCopyBuf>) -> Op,
{
// wrapper code
} |
One thing that the current interface does not support is for the plugin to have some "state" that persists between op calls. Using a function trait for op dispatchers might be the solution, although we'd need to use I think adding functionality to |
I figure it would be pretty hard to wrap a function without capturing said function.
Would require a static lifetime for that reference, so not really ideal. Unless there is some simple way to provide a static reference to a closure. Edit: it's possible to avoid static, but as you said " difficult to deal with the lifetime constraints". Are there any other reasons to avoid Also for a little context I'm working on a common version of |
But it is possible (thanks to rusts "function item types"). |
The main real example I can find is the Lines 47 to 101 in aa1284c
I think a simpler example might be: a function that returns a closure that captures a owned immutable value. fn generate_op(result: &[u8]) -> impl Fn(&mut dyn Interface, &[u8], Option<ZeroCopyBuf>) -> Op {
move |_interface: &mut dyn Interface,
data: &[u8],
zero_copy: Option<ZeroCopyBuf>| -> Op {
if let Some(buf) = zero_copy {
let data_str = std::str::from_utf8(&data[..]).unwrap();
let buf_str = std::str::from_utf8(&buf[..]).unwrap();
println!(
"Hello from plugin. data: {} | zero_copy: {}",
data_str, buf_str
);
}
let result_box: Buf = Box::new(*result); // Note usage of result
Op::Sync(result_box)
}
} Is there some way to return a |
No, that is not possible.
Yes, then it would be possible. |
BTW, I've been looking at #4434. pub trait DispatchOpFn:
Fn(&mut dyn Interface, &[u8], Option<ZeroCopyBuf>) -> Op
{
fn box_op(self) -> Box<dyn DispatchOpFn>;
} ^-- That |
Turns out that using It also causes what I assume is a different segfault on windows. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
There doesn't appear to be a way to make our existing pattern of op wrappers work with plugin ops.
We can't just change the signature of
Interface::register_op
and use aFn
as it's a trait and isn't sized. We also can't use a generic here if we want to useInterface
as a object(&mut dyn Interface
). We can useBox<Fn>
, but I would rather not as that diverges from normal ops.The text was updated successfully, but these errors were encountered: