11/*
2- * Copyright (c) 2006-2024 , RT-Thread Development Team
2+ * Copyright (c) 2006-2025 , RT-Thread Development Team
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 *
88 * 2025-10-14 foxglove libdl safe wrapper (libloading-like)
99 */
1010
11- //! Minimal `libloading`-style safe wrapper around RT-Thread libdl.
12- //! Provides RAII `Library` and typed `Symbol<T>` for dlsym.
11+ /*! Minimal `libloading`-style safe wrapper around RT-Thread libdl.
12+ Provides RAII `Library` and typed `Symbol<T>` for dlsym.
13+ */
1314
1415extern crate alloc;
1516
@@ -26,13 +27,13 @@ use crate::bindings::libc;
2627
2728pub use crate :: bindings:: libc:: { RTLD_GLOBAL , RTLD_LAZY , RTLD_LOCAL , RTLD_NOW } ;
2829
29- /// Error type for dynamic loading operations
30+ /* Error type for dynamic loading operations */
3031pub enum DlError {
31- /// dlopen failed; contains last error C-string pointer
32+ /* dlopen failed; contains last error C-string pointer */
3233 Open ( * const c_char ) ,
33- /// dlsym failed; contains last error C-string pointer
34+ /* dlsym failed; contains last error C-string pointer */
3435 Symbol ( * const c_char ) ,
35- /// dlclose returned non-zero; contains return code
36+ /* dlclose returned non-zero; contains return code */
3637 Close ( c_int ) ,
3738}
3839
@@ -64,27 +65,27 @@ impl core::fmt::Display for DlError {
6465 }
6566}
6667
67- /// RAII wrapper for a `dlopen` handle
68+ /* RAII wrapper for a `dlopen` handle */
6869pub struct Library {
6970 handle : * mut c_void ,
7071}
7172
7273impl Library {
73- /// Create a new library using default flags (`RTLD_NOW | RTLD_GLOBAL`).
74- /// Accepts a Rust string path and converts internally to a C string.
74+ /* Create a new library using default flags (`RTLD_NOW | RTLD_GLOBAL`).
75+ * Accepts a Rust string path and converts internally to a C string.
76+ */
7577 pub fn new ( path : & str ) -> Result < Self , DlError > {
76- // Convert to NUL-terminated C string; reject interior NULs
7778 let cstr = match CString :: new ( path) {
7879 Ok ( s) => s,
7980 Err ( _) => {
80- // Interior NUL; no last_error available, return a neutral error
8181 return Err ( DlError :: Open ( core:: ptr:: null ( ) ) ) ;
8282 }
8383 } ;
8484 unsafe { Self :: open_global ( cstr. as_ptr ( ) ) }
8585 }
86- /// Open a dynamic module with given flags
87- /// Safety: `path` must be a valid, NUL-terminated C string pointer
86+ /* Open a dynamic module with given flags
87+ * Safety: `path` must be a valid, NUL-terminated C string pointer
88+ */
8889 pub unsafe fn open ( path : * const c_char , flags : c_int ) -> Result < Self , DlError > {
8990 let h = libc:: dlopen ( path, flags) ;
9091 if h. is_null ( ) {
@@ -94,13 +95,14 @@ impl Library {
9495 }
9596 }
9697
97- /// Convenience open using `RTLD_NOW | RTLD_GLOBAL`
98+ /* Convenience open using `RTLD_NOW | RTLD_GLOBAL` */
9899 pub unsafe fn open_global ( path : * const c_char ) -> Result < Self , DlError > {
99100 Self :: open ( path, RTLD_NOW | RTLD_GLOBAL )
100101 }
101102
102- /// Resolve a typed symbol from the library using a C string pointer.
103- /// Safety: Caller must ensure `T` matches the actual symbol type and `symbol` is NUL-terminated.
103+ /* Resolve a typed symbol from the library using a C string pointer.
104+ * Safety: Caller must ensure `T` matches the actual symbol type and `symbol` is NUL-terminated.
105+ */
104106 pub unsafe fn get_ptr < T > ( & self , symbol : * const c_char ) -> Result < Symbol < ' _ , T > , DlError > {
105107 let sym = libc:: dlsym ( self . handle , symbol) ;
106108 if sym. is_null ( ) {
@@ -114,8 +116,9 @@ impl Library {
114116 }
115117 }
116118
117- /// Resolve a typed symbol from the library using a byte slice name.
118- /// If the slice is not NUL-terminated, a temporary buffer is allocated.
119+ /* Resolve a typed symbol from the library using a byte slice name.
120+ * If the slice is not NUL-terminated, a temporary buffer is allocated.
121+ */
119122 pub fn get < T > ( & self , symbol : & [ u8 ] ) -> Result < Symbol < ' _ , T > , DlError > {
120123 let ( ptr, _guard_buf) : ( * const c_char , Option < Vec < u8 > > ) = if symbol. last ( ) . copied ( ) == Some ( 0 ) {
121124 ( symbol. as_ptr ( ) as * const c_char , None )
@@ -125,7 +128,6 @@ impl Library {
125128 buf. push ( 0 ) ;
126129 ( buf. as_ptr ( ) as * const c_char , Some ( buf) )
127130 } ;
128- // Call into dlsym; buffer lives until end of this function
129131 let sym = unsafe { libc:: dlsym ( self . handle , ptr) } ;
130132 if sym. is_null ( ) {
131133 Err ( DlError :: Symbol ( libc:: last_error_ptr ( ) ) )
@@ -138,12 +140,12 @@ impl Library {
138140 }
139141 }
140142
141- /// Check if handle is null
143+ /* Check if handle is null */
142144 pub fn is_null ( & self ) -> bool {
143145 self . handle . is_null ( )
144146 }
145147
146- /// Consume and close the library explicitly
148+ /* Consume and close the library explicitly */
147149 pub unsafe fn close ( self ) -> Result < ( ) , DlError > {
148150 let h = self . handle ;
149151 forget ( self ) ;
@@ -155,7 +157,7 @@ impl Library {
155157 }
156158 }
157159
158- /// Leak the handle out (caller manages lifetime)
160+ /* Leak the handle out (caller manages lifetime) */
159161 pub unsafe fn into_raw ( self ) -> * mut c_void {
160162 let h = self . handle ;
161163 forget ( self ) ;
@@ -174,33 +176,36 @@ impl Drop for Library {
174176 }
175177}
176178
177- /// RAII wrapper for a symbol tied to a `Library` lifetime.
178- /// Stores the raw pointer and performs typed conversion at the use site.
179+ /* RAII wrapper for a symbol tied to a `Library` lifetime.
180+ * Stores the raw pointer and performs typed conversion at the use site.
181+ */
179182pub struct Symbol < ' lib , T > {
180183 raw : * mut c_void ,
181184 _lib : PhantomData < & ' lib Library > ,
182185 _ty : PhantomData < T > ,
183186}
184187
185188impl < ' lib , T > Symbol < ' lib , T > {
186- /// Check if the underlying pointer is null
189+ /* Check if the underlying pointer is null */
187190 pub fn is_null ( & self ) -> bool {
188191 self . raw . is_null ( )
189192 }
190193
191- /// Get the raw pointer as `*mut c_void`
194+ /* Get the raw pointer as `*mut c_void` */
192195 pub fn as_raw ( & self ) -> * mut c_void {
193196 self . raw
194197 }
195198
196- /// Cast the raw pointer to a different pointer type
197- /// Safety: Caller must ensure `U` is the correct target type.
199+ /* Cast the raw pointer to a different pointer type
200+ * Safety: Caller must ensure `U` is the correct target type.
201+ */
198202 pub unsafe fn as_ptr < U > ( & self ) -> * mut U {
199203 self . raw as * mut U
200204 }
201205
202- /// Convert to the typed value (e.g., function pointer) at use site
203- /// Safety: `T` must be the correct type for the symbol.
206+ /* Convert to the typed value (e.g., function pointer) at use site
207+ Safety: `T` must be the correct type for the symbol.
208+ */
204209 pub unsafe fn to_value ( & self ) -> T
205210 where
206211 T : Sized + Copy ,
@@ -211,7 +216,6 @@ impl<'lib, T> Symbol<'lib, T> {
211216 core:: ptr:: read ( src)
212217 }
213218
214- /// Consume the wrapper and return the raw pointer
215219 pub fn into_raw ( self ) -> * mut c_void {
216220 let p = self . raw ;
217221 forget ( self ) ;
@@ -222,13 +226,12 @@ impl<'lib, T> Symbol<'lib, T> {
222226impl < ' lib , T > Deref for Symbol < ' lib , T > {
223227 type Target = T ;
224228 fn deref ( & self ) -> & Self :: Target {
225- // Reinterpret the `raw` pointer storage as a value of type `T`.
226- // This is safe if `T` is a pointer-sized function pointer or compatible pointer type.
229+ /* Reinterpret the `raw` pointer storage as a value of type `T`. */
230+ /* Safety: This is safe if `T` is a pointer-sized function pointer or compatible pointer type. */
227231 unsafe { & * ( ( & self . raw as * const * mut c_void ) as * const T ) }
228232 }
229233}
230234
231- /// Fetch last libc error C-string pointer (for printing)
232235#[ inline]
233236pub fn last_error ( ) -> * const c_char {
234237 libc:: last_error_ptr ( )
0 commit comments