0
votes

I'm trying to wrap a FFI in a Rust Safe way. The FFI Exposes raw pointers to structs with vtables, basically a struct looks like this:

pub struct InterfaceVTBL {
    pub Release: unsafe extern "system" fn(This: *mut Interface) -> u64
}

pub struct Interface {
    pub lpVtbl: *const InterfaceVTBL,
}

impl Interface {
    pub unsafe fn Release(&self) -> u64 {
        ((*self.lpVtbl).Release)(self as *const _ as *mut _)
    }
}

The Release Method is important, because it has to be called, when you are finished using the pointer to avoid a memory leak.

Now, im currently wrapping the pointers i get into Container Structs like this:

pub struct InterfaceContainer {
    interface: *mut Interface
}

impl InterfaceContainer {
    fn Release(&mut self) {
        let reference = &*self.interface;
        reference.Release();
    }
}

impl Drop for InterfaceContainer {
    fn drop(&mut self) {
        self.Release();
    }
}

Notice, that i didn't make the Release function of the Container pub, because it really should only be called on drop.

Now, the problem i'm facing, is that i need to pass the raw pointer to the interface to FFI Functions that will most likely be in different modules than the container structs, so they can't access the raw pointers in the Containers.

I could of course make the pointers pub or add a get_ptr function that returns a reference to the pointer, but i think that would defeat the purpose of wrapping the pointer in the first place, since all restrictions on function use through the pointers could be circumvented.

Now, im asking, is there a different way of exposing the pointer to those functions only, that i missed, or do i have to use an entirely different approach to wrapping those pointers?

Answers are much appreciated, thanks in advance.

1

1 Answers

0
votes

Found a Solution:

Using pub (crate), the internal pointer can be made accessible only to code in the crate and not to outside users.