pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/778ff236894a5808e58e585cc0c296adda14cc3f

69241e157469407.css" /> [3.14] gh-78773: Improve ctypes dynamic library loading docs (GH-145… · python/cpython@778ff23 · GitHub
Skip to content

Commit 778ff23

Browse files
[3.14] gh-78773: Improve ctypes dynamic library loading docs (GH-145313) (GH-145674)
(cherry picked from commit d64f83d) Co-authored-by: Petr Viktorin <encukou@gmail.com>
1 parent b194688 commit 778ff23

File tree

1 file changed

+133
-117
lines changed

1 file changed

+133
-117
lines changed

Doc/library/ctypes.rst

Lines changed: 133 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ used to wrap these libraries in pure Python.
2222
ctypes tutorial
2323
---------------
2424

25-
Note: The code samples in this tutorial use :mod:`doctest` to make sure that
26-
they actually work. Since some code samples behave differently under Linux,
27-
Windows, or macOS, they contain doctest directives in comments.
28-
2925
Note: Some code samples reference the ctypes :class:`c_int` type. On platforms
3026
where ``sizeof(long) == sizeof(int)`` it is an alias to :class:`c_long`.
3127
So, you should not be confused if :class:`c_long` is printed if you would expect
@@ -36,13 +32,16 @@ So, you should not be confused if :class:`c_long` is printed if you would expect
3632
Loading dynamic link libraries
3733
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3834

39-
:mod:`!ctypes` exports the *cdll*, and on Windows *windll* and *oledll*
35+
:mod:`!ctypes` exports the :py:data:`~ctypes.cdll`, and on Windows
36+
:py:data:`~ctypes.windll` and :py:data:`~ctypes.oledll`
4037
objects, for loading dynamic link libraries.
4138

42-
You load libraries by accessing them as attributes of these objects. *cdll*
43-
loads libraries which export functions using the standard ``cdecl`` calling
44-
convention, while *windll* libraries call functions using the ``stdcall``
45-
calling convention. *oledll* also uses the ``stdcall`` calling convention, and
39+
You load libraries by accessing them as attributes of these objects.
40+
:py:data:`!cdll` loads libraries which export functions using the
41+
standard ``cdecl`` calling convention, while :py:data:`!windll`
42+
libraries call functions using the ``stdcall``
43+
calling convention.
44+
:py:data:`~oledll` also uses the ``stdcall`` calling convention, and
4645
assumes the functions return a Windows :c:type:`!HRESULT` error code. The error
4746
code is used to automatically raise an :class:`OSError` exception when the
4847
function call fails.
@@ -72,11 +71,13 @@ Windows appends the usual ``.dll`` file suffix automatically.
7271
being used by Python. Where possible, use native Python functionality,
7372
or else import and use the ``msvcrt`` module.
7473

75-
On Linux, it is required to specify the filename *including* the extension to
74+
Other systems require the filename *including* the extension to
7675
load a library, so attribute access can not be used to load libraries. Either the
7776
:meth:`~LibraryLoader.LoadLibrary` method of the dll loaders should be used,
78-
or you should load the library by creating an instance of CDLL by calling
79-
the constructor::
77+
or you should load the library by creating an instance of :py:class:`CDLL`
78+
by calling the constructor.
79+
80+
For example, on Linux::
8081

8182
>>> cdll.LoadLibrary("libc.so.6") # doctest: +LINUX
8283
<CDLL 'libc.so.6', handle ... at ...>
@@ -85,7 +86,14 @@ the constructor::
8586
<CDLL 'libc.so.6', handle ... at ...>
8687
>>>
8788

88-
.. XXX Add section for macOS.
89+
On macOS::
90+
91+
>>> cdll.LoadLibrary("libc.dylib") # doctest: +MACOS
92+
<CDLL 'libc.dylib', handle ... at ...>
93+
>>> libc = CDLL("libc.dylib") # doctest: +MACOS
94+
>>> libc # doctest: +MACOS
95+
<CDLL 'libc.dylib', handle ... at ...>
96+
8997

9098

9199
.. _ctypes-accessing-functions-from-loaded-dlls:
@@ -1458,14 +1466,82 @@ Loading shared libraries
14581466
^^^^^^^^^^^^^^^^^^^^^^^^
14591467

14601468
There are several ways to load shared libraries into the Python process. One
1461-
way is to instantiate one of the following classes:
1469+
way is to instantiate :py:class:`CDLL` or one of its subclasses:
14621470

14631471

14641472
.. class:: CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None)
14651473

1466-
Instances of this class represent loaded shared libraries. Functions in these
1467-
libraries use the standard C calling convention, and are assumed to return
1468-
:c:expr:`int`.
1474+
Represents a loaded shared library.
1475+
1476+
Functions in this library use the standard C calling convention, and are
1477+
assumed to return :c:expr:`int`.
1478+
The Python :term:`global interpreter lock` is released before calling any
1479+
function exported by these libraries, and reacquired afterwards.
1480+
For different function behavior, use a subclass: :py:class:`~ctypes.OleDLL`,
1481+
:py:class:`~ctypes.WinDLL`, or :py:class:`~ctypes.PyDLL`.
1482+
1483+
If you have an existing :py:attr:`handle <ctypes.CDLL._handle>` to an already
1484+
loaded shared library, it can be passed as the *handle* argument to wrap
1485+
the opened library in a new :py:class:`!CDLL` object.
1486+
In this case, *name* is only used to set the :py:attr:`~ctypes.CDLL._name`
1487+
attribute, but it may be adjusted and/or validated.
1488+
1489+
If *handle* is ``None``, the underlying platform's :manpage:`dlopen(3)` or
1490+
:c:func:`!LoadLibrary` function is used to load the library into
1491+
the process, and to get a handle to it.
1492+
1493+
*name* is the pathname of the shared library to open.
1494+
If *name* does not contain a path separator, the library is found
1495+
in a platform-specific way.
1496+
1497+
On non-Windows systems, *name* can be ``None``. In this case,
1498+
:c:func:`!dlopen` is called with ``NULL``, which opens the main program
1499+
as a "library".
1500+
(Some systems do the same is *name* is empty; ``None``/``NULL`` is more
1501+
portable.)
1502+
1503+
.. admonition:: CPython implementation detail
1504+
1505+
Since CPython is linked to ``libc``, a ``None`` *name* is often used
1506+
to access the C standard library::
1507+
1508+
>>> printf = ctypes.CDLL(None).printf
1509+
>>> printf.argtypes = [ctypes.c_char_p]
1510+
>>> printf(b"hello\n")
1511+
hello
1512+
6
1513+
1514+
To access the Python C API, prefer :py:data:`ctypes.pythonapi` which
1515+
works across platforms.
1516+
1517+
The *mode* parameter can be used to specify how the library is loaded. For
1518+
details, consult the :manpage:`dlopen(3)` manpage. On Windows, *mode* is
1519+
ignored. On posix systems, RTLD_NOW is always added, and is not
1520+
configurable.
1521+
1522+
The *use_errno* parameter, when set to true, enables a ctypes mechanism that
1523+
allows accessing the system :data:`errno` error number in a safe way.
1524+
:mod:`!ctypes` maintains a thread-local copy of the system's :data:`errno`
1525+
variable; if you call foreign functions created with ``use_errno=True`` then the
1526+
:data:`errno` value before the function call is swapped with the ctypes private
1527+
copy, the same happens immediately after the function call.
1528+
1529+
The function :func:`ctypes.get_errno` returns the value of the ctypes private
1530+
copy, and the function :func:`ctypes.set_errno` changes the ctypes private copy
1531+
to a new value and returns the former value.
1532+
1533+
The *use_last_error* parameter, when set to true, enables the same mechanism for
1534+
the Windows error code which is managed by the :func:`GetLastError` and
1535+
:func:`!SetLastError` Windows API functions; :func:`ctypes.get_last_error` and
1536+
:func:`ctypes.set_last_error` are used to request and change the ctypes private
1537+
copy of the windows error code.
1538+
1539+
The *winmode* parameter is used on Windows to specify how the library is loaded
1540+
(since *mode* is ignored). It takes any value that is valid for the Win32 API
1541+
``LoadLibraryEx`` flags parameter. When omitted, the default is to use the
1542+
flags that result in the most secure DLL load, which avoids issues such as DLL
1543+
hijacking. Passing the full path to the DLL is the safest way to ensure the
1544+
correct library and dependencies are loaded.
14691545

14701546
On Windows creating a :class:`CDLL` instance may fail even if the DLL name
14711547
exists. When a dependent DLL of the loaded DLL is not found, a
@@ -1477,20 +1553,47 @@ way is to instantiate one of the following classes:
14771553
DLLs and determine which one is not found using Windows debugging and
14781554
tracing tools.
14791555

1556+
.. seealso::
1557+
1558+
`Microsoft DUMPBIN tool <https://learn.microsoft.com/en-us/cpp/build/reference/dumpbin-reference?view=msvc-170>`_
1559+
-- A tool to find DLL dependents.
1560+
1561+
.. versionchanged:: 3.8
1562+
Added *winmode* parameter.
1563+
14801564
.. versionchanged:: 3.12
14811565

14821566
The *name* parameter can now be a :term:`path-like object`.
14831567

1484-
.. seealso::
1568+
Instances of this class have no public methods. Functions exported by the
1569+
shared library can be accessed as attributes or by index. Please note that
1570+
accessing the function through an attribute caches the result and therefore
1571+
accessing it repeatedly returns the same object each time. On the other hand,
1572+
accessing it through an index returns a new object each time::
1573+
1574+
>>> from ctypes import CDLL
1575+
>>> libc = CDLL("libc.so.6") # On Linux
1576+
>>> libc.time == libc.time
1577+
True
1578+
>>> libc['time'] == libc['time']
1579+
False
1580+
1581+
The following public attributes are available. Their name starts with an
1582+
underscore to not clash with exported function names:
1583+
1584+
.. attribute:: _handle
1585+
1586+
The system handle used to access the library.
14851587

1486-
`Microsoft DUMPBIN tool <https://docs.microsoft.com/cpp/build/reference/dependents>`_
1487-
-- A tool to find DLL dependents.
1588+
.. attribute:: _name
14881589

1590+
The name of the library passed in the constructor.
14891591

1490-
.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None)
1592+
.. class:: OleDLL
14911593

1492-
Instances of this class represent loaded shared libraries,
1493-
functions in these libraries use the ``stdcall`` calling convention, and are
1594+
See :py:class:`~ctypes.CDLL`, the superclass, for common information.
1595+
1596+
Functions in this library use the ``stdcall`` calling convention, and are
14941597
assumed to return the windows specific :class:`HRESULT` code. :class:`HRESULT`
14951598
values contain information specifying whether the function call failed or
14961599
succeeded, together with additional error code. If the return value signals a
@@ -1502,133 +1605,51 @@ way is to instantiate one of the following classes:
15021605
:exc:`WindowsError` used to be raised,
15031606
which is now an alias of :exc:`OSError`.
15041607

1505-
.. versionchanged:: 3.12
1506-
1507-
The *name* parameter can now be a :term:`path-like object`.
15081608

1609+
.. class:: WinDLL
15091610

1510-
.. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None)
1611+
See :py:class:`~ctypes.CDLL`, the superclass, for common information.
15111612

1512-
Instances of this class represent loaded shared libraries,
1513-
functions in these libraries use the ``stdcall`` calling convention, and are
1613+
Functions in these libraries use the ``stdcall`` calling convention, and are
15141614
assumed to return :c:expr:`int` by default.
15151615

15161616
.. availability:: Windows
15171617

1518-
.. versionchanged:: 3.12
1618+
.. class:: PyDLL
15191619

1520-
The *name* parameter can now be a :term:`path-like object`.
1620+
See :py:class:`~ctypes.CDLL`, the superclass, for common information.
15211621

1522-
1523-
The Python :term:`global interpreter lock` is released before calling any
1524-
function exported by these libraries, and reacquired afterwards.
1525-
1526-
1527-
.. class:: PyDLL(name, mode=DEFAULT_MODE, handle=None)
1528-
1529-
Instances of this class behave like :class:`CDLL` instances, except that the
1622+
When functions in this library are called, the
15301623
Python GIL is *not* released during the function call, and after the function
15311624
execution the Python error flag is checked. If the error flag is set, a Python
15321625
exception is raised.
15331626

1534-
Thus, this is only useful to call Python C api functions directly.
1535-
1536-
.. versionchanged:: 3.12
1537-
1538-
The *name* parameter can now be a :term:`path-like object`.
1539-
1540-
All these classes can be instantiated by calling them with at least one
1541-
argument, the pathname of the shared library. If you have an existing handle to
1542-
an already loaded shared library, it can be passed as the ``handle`` named
1543-
parameter, otherwise the underlying platform's :c:func:`!dlopen` or
1544-
:c:func:`!LoadLibrary` function is used to load the library into
1545-
the process, and to get a handle to it.
1546-
1547-
The *mode* parameter can be used to specify how the library is loaded. For
1548-
details, consult the :manpage:`dlopen(3)` manpage. On Windows, *mode* is
1549-
ignored. On posix systems, RTLD_NOW is always added, and is not
1550-
configurable.
1551-
1552-
The *use_errno* parameter, when set to true, enables a ctypes mechanism that
1553-
allows accessing the system :data:`errno` error number in a safe way.
1554-
:mod:`!ctypes` maintains a thread-local copy of the system's :data:`errno`
1555-
variable; if you call foreign functions created with ``use_errno=True`` then the
1556-
:data:`errno` value before the function call is swapped with the ctypes private
1557-
copy, the same happens immediately after the function call.
1558-
1559-
The function :func:`ctypes.get_errno` returns the value of the ctypes private
1560-
copy, and the function :func:`ctypes.set_errno` changes the ctypes private copy
1561-
to a new value and returns the former value.
1562-
1563-
The *use_last_error* parameter, when set to true, enables the same mechanism for
1564-
the Windows error code which is managed by the :func:`GetLastError` and
1565-
:func:`!SetLastError` Windows API functions; :func:`ctypes.get_last_error` and
1566-
:func:`ctypes.set_last_error` are used to request and change the ctypes private
1567-
copy of the windows error code.
1568-
1569-
The *winmode* parameter is used on Windows to specify how the library is loaded
1570-
(since *mode* is ignored). It takes any value that is valid for the Win32 API
1571-
``LoadLibraryEx`` flags parameter. When omitted, the default is to use the
1572-
flags that result in the most secure DLL load, which avoids issues such as DLL
1573-
hijacking. Passing the full path to the DLL is the safest way to ensure the
1574-
correct library and dependencies are loaded.
1575-
1576-
.. versionchanged:: 3.8
1577-
Added *winmode* parameter.
1627+
Thus, this is only useful to call Python C API functions directly.
15781628

15791629

15801630
.. data:: RTLD_GLOBAL
1581-
:noindex:
15821631

15831632
Flag to use as *mode* parameter. On platforms where this flag is not available,
15841633
it is defined as the integer zero.
15851634

15861635

15871636
.. data:: RTLD_LOCAL
1588-
:noindex:
15891637

15901638
Flag to use as *mode* parameter. On platforms where this is not available, it
15911639
is the same as *RTLD_GLOBAL*.
15921640

15931641

15941642
.. data:: DEFAULT_MODE
1595-
:noindex:
15961643

15971644
The default mode which is used to load shared libraries. On OSX 10.3, this is
15981645
*RTLD_GLOBAL*, otherwise it is the same as *RTLD_LOCAL*.
15991646

1600-
Instances of these classes have no public methods. Functions exported by the
1601-
shared library can be accessed as attributes or by index. Please note that
1602-
accessing the function through an attribute caches the result and therefore
1603-
accessing it repeatedly returns the same object each time. On the other hand,
1604-
accessing it through an index returns a new object each time::
1605-
1606-
>>> from ctypes import CDLL
1607-
>>> libc = CDLL("libc.so.6") # On Linux
1608-
>>> libc.time == libc.time
1609-
True
1610-
>>> libc['time'] == libc['time']
1611-
False
1612-
1613-
The following public attributes are available, their name starts with an
1614-
underscore to not clash with exported function names:
1615-
1616-
1617-
.. attribute:: PyDLL._handle
1618-
1619-
The system handle used to access the library.
1620-
1621-
1622-
.. attribute:: PyDLL._name
1623-
1624-
The name of the library passed in the constructor.
16251647

16261648
Shared libraries can also be loaded by using one of the prefabricated objects,
16271649
which are instances of the :class:`LibraryLoader` class, either by calling the
16281650
:meth:`~LibraryLoader.LoadLibrary` method, or by retrieving the library as
16291651
attribute of the loader instance.
16301652

1631-
16321653
.. class:: LibraryLoader(dlltype)
16331654

16341655
Class which loads shared libraries. *dlltype* should be one of the
@@ -1647,29 +1668,25 @@ attribute of the loader instance.
16471668
These prefabricated library loaders are available:
16481669

16491670
.. data:: cdll
1650-
:noindex:
16511671

16521672
Creates :class:`CDLL` instances.
16531673

16541674

16551675
.. data:: windll
1656-
:noindex:
16571676

16581677
Creates :class:`WinDLL` instances.
16591678

16601679
.. availability:: Windows
16611680

16621681

16631682
.. data:: oledll
1664-
:noindex:
16651683

16661684
Creates :class:`OleDLL` instances.
16671685

16681686
.. availability:: Windows
16691687

16701688

16711689
.. data:: pydll
1672-
:noindex:
16731690

16741691
Creates :class:`PyDLL` instances.
16751692

@@ -1678,7 +1695,6 @@ For accessing the C Python api directly, a ready-to-use Python shared library
16781695
object is available:
16791696

16801697
.. data:: pythonapi
1681-
:noindex:
16821698

16831699
An instance of :class:`PyDLL` that exposes Python C API functions as
16841700
attributes. Note that all these functions are assumed to return C

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy