Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Box<Any> downcast return None in dylib module

Tags:

rust

I use dylib as plugin solution. When I call function register(in the code below, fun is my project name):

let register = plugin.get::<unsafe extern fn(&mut fun::mem::Mem)>("register").unwrap();
unsafe {
    register(&mut mem);
}

In dylib's register function, mem.get_mut::<fun::router::Router>("router") return None

But if I use mem.get_mut::<fun::router::Router>("router") in main.rs. It return Router as I want.

I test more and get some result below:

In dylib:

  • mem.get_mut::<String>("test") work well.
  • mem.get_mut::<fun::Bob>("bob") return None.

In main.rs:

  • mem.get_mut::<String>("test") work well.
  • mem.get_mut::<fun::Bob>("bob") work well.

My question:

Why downcast_mut return None in dylib if downcast's generic type defined in Main module ?

mem struct:

#[derive(Debug)]
pub struct Mem {
    pub value: HashMap<String, Box<Any>>,
}

get_mut:

pub fn get_mut<T: Any>(&mut self, key: &str) -> Option<&mut T> {
    match self.value.get_mut(key) {
        Some(val) => {
            match val.downcast_mut::<T>() {
                Some(value) => Some(value),
                None => None,
            }
        }
        None => None,
    }
}

Sorry for my poor description.

Update:

TypeId test result:

# in dylib's function:
Router TypeId: TypeId { t: 10245301028242226491 }
String TypeId: TypeId { t: 2231836747111135853 }

# in `main.rs`'s function:
Router TypeId: TypeId { t: 11005875220745415326 }
String TypeId: TypeId { t: 2231836747111135853 }

TypeId is different. Any solution for this problem?

like image 297
Feng Cen Avatar asked Jul 31 '16 11:07

Feng Cen


1 Answers

As mentioned, up until now (1.10) the TypeId is not stable across crates or compilations.

@eddyb just this week landed a pull request which makes TypeId unique cross-crate which will enable your particular usecase.

It is important to note that this stability is not complete; if you read down the comments, for example, you will note that the TypeId may change if the compiler version or crate version changes. Still, for a single compiler and shared dependency, it's now stable across re-compilations.

For now, you can either use a nightly compiler, or wait until the next stable version which will contain this patch (1.12 or 1.13 I suppose).

like image 187
Matthieu M. Avatar answered Nov 04 '22 01:11

Matthieu M.