@@ -199,16 +199,30 @@ pub(crate) mod _ctypes {
199199
200200 #[ pyfunction( name = "dlopen" ) ]
201201 fn load_library_unix (
202- name : String ,
202+ name : Option < String > ,
203203 _load_flags : OptionalArg < i32 > ,
204204 vm : & VirtualMachine ,
205205 ) -> PyResult < usize > {
206206 // TODO: audit functions first
207207 // TODO: load_flags
208- let cache = library:: libcache ( ) ;
209- let mut cache_write = cache. write ( ) ;
210- let ( id, _) = cache_write. get_or_insert_lib ( & name, vm) . unwrap ( ) ;
211- Ok ( id)
208+ match name {
209+ Some ( name) => {
210+ let cache = library:: libcache ( ) ;
211+ let mut cache_write = cache. write ( ) ;
212+ let ( id, _) = cache_write
213+ . get_or_insert_lib ( & name, vm)
214+ . map_err ( |e| vm. new_os_error ( e. to_string ( ) ) ) ?;
215+ Ok ( id)
216+ }
217+ None => {
218+ // If None, call libc::dlopen(null, mode) to get the current process handle
219+ let handle = unsafe { libc:: dlopen ( std:: ptr:: null ( ) , libc:: RTLD_NOW ) } ;
220+ if handle. is_null ( ) {
221+ return Err ( vm. new_os_error ( "dlopen() error" . to_string ( ) ) ) ;
222+ }
223+ Ok ( handle as usize )
224+ }
225+ }
212226 }
213227
214228 #[ pyfunction( name = "FreeLibrary" ) ]
@@ -220,10 +234,57 @@ pub(crate) mod _ctypes {
220234 }
221235
222236 #[ pyfunction( name = "POINTER" ) ]
223- pub fn pointer ( _cls : PyTypeRef ) { }
237+ pub fn create_pointer_type ( cls : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
238+ // Get the _pointer_type_cache
239+ let ctypes_module = vm. import ( "_ctypes" , 0 ) ?;
240+ let cache = ctypes_module. get_attr ( "_pointer_type_cache" , vm) ?;
241+
242+ // Check if already in cache using __getitem__
243+ if let Ok ( cached) = vm. call_method ( & cache, "__getitem__" , ( cls. clone ( ) , ) ) {
244+ if !vm. is_none ( & cached) {
245+ return Ok ( cached) ;
246+ }
247+ }
248+
249+ // Get the _Pointer base class
250+ let pointer_base = ctypes_module. get_attr ( "_Pointer" , vm) ?;
251+
252+ // Create the name for the pointer type
253+ let name = if let Ok ( type_obj) = cls. get_attr ( "__name__" , vm) {
254+ format ! ( "LP_{}" , type_obj. str ( vm) ?)
255+ } else if let Ok ( s) = cls. str ( vm) {
256+ format ! ( "LP_{}" , s)
257+ } else {
258+ "LP_unknown" . to_string ( )
259+ } ;
260+
261+ // Create a new type that inherits from _Pointer
262+ let type_type = & vm. ctx . types . type_type ;
263+ let bases = vm. ctx . new_tuple ( vec ! [ pointer_base] ) ;
264+ let dict = vm. ctx . new_dict ( ) ;
265+ dict. set_item ( "_type_" , cls. clone ( ) , vm) ?;
266+
267+ let new_type = type_type
268+ . as_object ( )
269+ . call ( ( vm. ctx . new_str ( name) , bases, dict) , vm) ?;
270+
271+ // Store in cache using __setitem__
272+ vm. call_method ( & cache, "__setitem__" , ( cls, new_type. clone ( ) ) ) ?;
273+
274+ Ok ( new_type)
275+ }
224276
225277 #[ pyfunction( name = "pointer" ) ]
226- pub fn pointer_fn ( _inst : PyObjectRef ) { }
278+ pub fn create_pointer_inst ( obj : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
279+ // Get the type of the object
280+ let obj_type = obj. class ( ) . to_owned ( ) ;
281+
282+ // Create pointer type for this object's type
283+ let ptr_type = create_pointer_type ( obj_type. into ( ) , vm) ?;
284+
285+ // Create an instance of the pointer type with the object
286+ ptr_type. call ( ( obj, ) , vm)
287+ }
227288
228289 #[ pyfunction]
229290 fn _pointer_type_cache ( ) -> PyObjectRef {
0 commit comments