(ptr, free_func)
Creates a finalizer for a ctypes pointer.

  Args:
    ptr: A `ctypes.POINTER` to be freed.
    free_func: A callable that frees the pointer. It will be called with `ptr`
      as its only argument when `ptr` is garbage collected.
Creates a finalizer for a ctypes pointer.
Creates a finalizer for a ctypes pointer .
def _create_finalizer(ptr, free_func):
  """Creates a finalizer for a ctypes pointer.

  Args:
    ptr: A `ctypes.POINTER` to be freed.
    free_func: A callable that frees the pointer. It will be called with `ptr`
      as its only argument when `ptr` is garbage collected.
  """
  ptr_type = type(ptr)
  address = ctypes.addressof(ptr.contents)

  if address not in _FINALIZERS:  # Only one finalizer needed per address.

    logging.debug("Allocated %s at %x", ptr_type.__name__, address)

    def callback(dead_ptr_ref):
      """A weakref callback that frees the resource held by a pointer."""
      del dead_ptr_ref  # Unused weakref to the dead ctypes pointer object.
      if address not in _FINALIZERS:
        # Someone had already explicitly called `call_finalizer_for_pointer`.
        return
      else:
        # Turn the address back into a pointer to be freed.
        if ctypes.cast is None:
          return
          # `ctypes.cast` might be None if the interpreter is in the process of
          # exiting. In this case it doesn't really matter whether or not we
          # explicitly free the pointer, since any remaining pointers will be
          # freed anyway when the process terminates. We bail out silently in
          # order to avoid logging an unsightly (but harmless) error.
        temp_ptr = ctypes.cast(address, ptr_type)
        free_func(temp_ptr)
        logging.debug("Freed %s at %x", ptr_type.__name__, address)
        del _FINALIZERS[address]  # Remove the weakref from the global cache.

    # Store weakrefs in a global cache so that they don't get garbage collected
    # before their referents.
    _FINALIZERS[address] = (weakref.ref(ptr, callback), callback)
def _create_finalizer ( ptr , free_func ) : ptr_type = type ( ptr ) address = ctypes . addressof ( ptr . contents ) if address not in _FINALIZERS : # Only one finalizer needed per address. logging . debug ( "Allocated %s at %x" , ptr_type . __name__ , address ) def callback ( dead_ptr_ref ) : """A weakref callback that frees the resource held by a pointer.""" del dead_ptr_ref # Unused weakref to the dead ctypes pointer object. if address not in _FINALIZERS : # Someone had already explicitly called `call_finalizer_for_pointer`. return else : # Turn the address back into a pointer to be freed. if ctypes . cast is None : return # `ctypes.cast` might be None if the interpreter is in the process of # exiting. In this case it doesn't really matter whether or not we # explicitly free the pointer, since any remaining pointers will be # freed anyway when the process terminates. We bail out silently in # order to avoid logging an unsightly (but harmless) error. temp_ptr = ctypes . cast ( address , ptr_type ) free_func ( temp_ptr ) logging . debug ( "Freed %s at %x" , ptr_type . __name__ , address ) del _FINALIZERS [ address ] # Remove the weakref from the global cache. # Store weakrefs in a global cache so that they don't get garbage collected # before their referents. _FINALIZERS [ address ] = ( weakref . ref ( ptr , callback ) , callback )