nagisa / rust_libloading

Bindings around the platform's dynamic library loading primitives with greatly improved memory safety.
https://docs.rs/libloading
ISC License
1.24k stars 102 forks source link

dlmopen support #36

Open SoniEx2 opened 6 years ago

nagisa commented 6 years ago

dlmopen seems like an awfully GNU-specific function that cannot be expressed in a manner portable between even unix targets.

I feel like it should be fine to expect people to bind this manually if they need the functionality provided by this function.

SoniEx2 commented 6 years ago

While dlmopen is often considered a GNU extension, the concept is not GNU-specific.

For one, Windows' DLL APIs are equivalent to dlmopen. In addition to that, dlmopen is also available on SunOS/Solaris.

It would be nice if other systems adopted it, as it allows coexistence of, say, Python 2 and Python 3 in the same process space, but in the meantime we should do our best to provide it where available, and panic at runtime otherwise (just a better option than not allowing the library to compile at all, but this is up to you, obviously).

If it becomes popular enough, this should be enough to get other systems to support it, as you don't usually want your ports to just panic at runtime.

nagisa commented 5 years ago

I still have found no indication that any other UNIX targets other than the GNU-based ones have this function available. It is not available on macOS for example.

we should do our best to provide it where available, and panic at runtime otherwise (just a better option than not allowing the library to compile at all, but this is up to you, obviously).

It would be possible to provide it under gnu target_abi cfg, but in that case it is not obvious to those using unix-specific APIs that dlmopen API is not available outside of GNU. Hmmm…

SoniEx2 commented 5 years ago

https://docs.oracle.com/cd/E86824_01/html/E54766/dlmopen-3c.html

nagisa commented 5 years ago

There’re methods to convert to/from raw OS primitives in 0.5.2 so you can dlmopen things manually and produce Library out of that.

aidancully commented 3 years ago

There’re methods to convert to/from raw OS primitives in 0.5.2 so you can dlmopen things manually and produce Library out of that.

I've done that in a local project... Any chance to expose some of your dlerror functionality, so that I can re-use the same mechanisms as you have if dlmopen fails?

nagisa commented 3 years ago

I wouldn't be opposed to exposing with_dlerror and a similar function for Windows in some shape or form, but some thought and changes will be necessary to make the API more suitable for pub.

ileixe commented 8 months ago

We've got this requirement unfortunately... :innocent: Is there viable workaround here? Can you locate how you overcome @aidancully ?

+        let name = CString::new(library).expect("invalid library name");
+        let pointer = unsafe { libc::dlmopen(LM_ID_NEWLM, name.as_ptr(), RTLD_LAZY | RTLD_LOCAL) };
+
+        if pointer.is_null() {
+              // I'm ignoring error here 
+        }
+
         let library = Rc::new(unsafe {
-            sys::MyLibrary::new(library)?,
+            sys::MyLibrary::from_library(Library::from(unix::Library::from_raw(pointer)))
         });

I followed what you meant. with_dlerror seems to be enough to use the API.

nagisa commented 8 months ago

I'll make with_dlerror public in https://github.com/nagisa/rust_libloading/pull/139. You should be able to write your code with proper error handling in place shortly (once I release 0.8.2)