code: def _glibc_version_string_ctypes() -> Optional[str]:
      """
      Fallback implementation of glibc_version_string using ctypes.
      """
      try:
          import ctypes
      except ImportError:
          return None
  
      # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
      # manpage says, "If filename is NULL, then the returned handle is for the
      # main program". This way we can let the linker do the work to figure out
      # which libc our process is actually using.
      #
      # We must also handle the special case where the executable is not a
      # dynamically linked executable. This can occur when using musl libc,
      # for example. In this situation, dlopen() will error, leading to an
      # OSError. Interestingly, at least in the case of musl, there is no
      # errno set on the OSError. The single string argument used to construct
      # OSError comes from libc itself and is therefore not portable to
      # hard code here. In any case, failure to call dlopen() means we
      # can proceed, so we bail on our attempt.
      try:
          process_namespace = ctypes.CDLL(None)
      except OSError:
          return None
  
      try:
          gnu_get_libc_version = process_namespace.gnu_get_libc_version
      except AttributeError:
          # Symbol doesn't exist -> therefore, we are not linked to
          # glibc.
          return None
  
      # Call gnu_get_libc_version, which returns a string like "2.5"
      gnu_get_libc_version.restype = ctypes.c_char_p
      version_str: str = gnu_get_libc_version()
      # py2 / py3 compatibility:
      if not isinstance(version_str, str):
          version_str = version_str.decode("ascii")
  
      return version_str
  
imports: import collections
  import contextlib
  import functools
  import os
  import re
  import sys
  import warnings
  from typing import Dict, Generator, Iterator, NamedTuple, Optional, Sequence, Tuple
  from ._elffile import EIClass, EIData, ELFFile, EMachine
label_desc: Use image node_id 6 for calling a global function with example usage: _glibc_version_string_ctypes() and returns: version_str, None, None, None