Python có con trỏ hàm không?

Trong trường hợp này, SWIG sẽ bọc con trỏ hàm giống như đối với tất cả các con trỏ khác. Tuy nhiên, để thực sự gọi hàm này từ một tập lệnh, bạn sẽ cần truyền một số loại đối tượng con trỏ hàm C. Trong C, điều này rất dễ dàng, bạn chỉ cần cung cấp tên hàm làm đối số như thế này

là một thư viện chức năng nước ngoài cho Python. Nó cung cấp các kiểu dữ liệu tương thích với C và cho phép gọi các hàm trong DLL hoặc thư viện dùng chung. Nó có thể được sử dụng để bọc các thư viện này bằng Python thuần túy

hướng dẫn ctypes

Ghi chú. Các mẫu mã trong hướng dẫn này sử dụng để đảm bảo rằng chúng thực sự hoạt động. Vì một số mẫu mã hoạt động khác nhau trong Linux, Windows hoặc macOS nên chúng chứa các lệnh doctest trong nhận xét

Ghi chú. Một số mẫu mã tham chiếu loại ctypes. Trên các nền tảng nơi

>>> windll.kernel32.GetModuleHandleA(32)  
Traceback (most recent call last):
  File "", line 1, in 
OSError: exception: access violation reading 0x00000020
>>>
4 nó là bí danh của. Vì vậy, bạn không nên nhầm lẫn nếu được in nếu bạn mong đợi - chúng thực sự là cùng một loại

Đang tải thư viện liên kết động

xuất cdll và trên các đối tượng Windll và oledll của Windows để tải các thư viện liên kết động

You load libraries by accessing them as attributes of these objects. cdll loads libraries which export functions using the standard

>>> windll.kernel32.GetModuleHandleA(32)  
Traceback (most recent call last):
  File "", line 1, in 
OSError: exception: access violation reading 0x00000020
>>>
9 calling convention, while windll libraries call functions using the
>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>
0 calling convention. oledll also uses the
>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>
0 calling convention, and assumes the functions return a Windows
>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>
2 error code. The error code is used to automatically raise an exception when the function call fails

Changed in version 3. 3. Windows errors used to raise , which is now an alias of .

Here are some examples for Windows. Note that

>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>
6 is the MS standard C library containing most standard C functions, and uses the cdecl calling convention

>>> from ctypes import *
>>> print(windll.kernel32)  

>>> print(cdll.msvcrt)      

>>> libc = cdll.msvcrt      
>>>

Windows appends the usual

>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>
7 file suffix automatically

Note

Accessing the standard C library through

>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>
8 will use an outdated version of the library that may be incompatible with the one being used by Python. Where possible, use native Python functionality, or else import and use the
>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>
6 module

On Linux, it is required to specify the filename including the extension to load a library, so attribute access can not be used to load libraries. Either the

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
00 method of the dll loaders should be used, or you should load the library by creating an instance of CDLL by calling the constructor

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>

Accessing functions from loaded dlls

Functions are accessed as attributes of dll objects

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>

Note that win32 system dlls like

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
01 and
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
02 often export ANSI as well as UNICODE versions of a function. The UNICODE version is exported with an
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
03 appended to the name, while the ANSI version is exported with an
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
04 appended to the name. The win32
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
05 function, which returns a module handle for a given module name, has the following C prototype, and a macro is used to expose one of them as
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
05 depending on whether UNICODE is defined or not

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);

windll does not try to select one of them by magic, you must access the version you need by specifying

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
07 or
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
08 explicitly, and then call it with bytes or string objects respectively

Sometimes, dlls export functions with names which aren’t valid Python identifiers, like

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
09. In this case you have to use to retrieve the function

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>

On Windows, some dlls export functions not by name but by ordinal. These functions can be accessed by indexing the dll object with the ordinal number

>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>

Calling functions

You can call these functions like any other Python callable. This example uses the

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
11 function, which returns system time in seconds since the Unix epoch, and the
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
12 function, which returns a win32 module handle

This example calls both functions with a

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
13 pointer (
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
14 should be used as the
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
13 pointer)

>>> print(libc.time(None))  
1150640792
>>> print(hex(windll.kernel32.GetModuleHandleA(None)))  
0x1d000000
>>>

is raised when you call an

>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>
0 function with the
>>> windll.kernel32.GetModuleHandleA(32)  
Traceback (most recent call last):
  File "", line 1, in 
OSError: exception: access violation reading 0x00000020
>>>
9 calling convention, or vice versa

>>> cdll.kernel32.GetModuleHandleA(None)  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>

>>> windll.msvcrt.printf(b"spam")  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>

To find out the correct calling convention you have to look into the C header file or the documentation for the function you want to call

On Windows, uses win32 structured exception handling to prevent crashes from general protection faults when functions are called with invalid argument values

>>> windll.kernel32.GetModuleHandleA(32)  
Traceback (most recent call last):
  File "", line 1, in 
OSError: exception: access violation reading 0x00000020
>>>

There are, however, enough ways to crash Python with , so you should be careful anyway. Mô-đun này có thể hữu ích trong việc gỡ lỗi sự cố (e. g. from segmentation faults produced by erroneous C library calls)

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
14, integers, bytes objects and (unicode) strings are the only native Python objects that can directly be used as parameters in these function calls.
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
14 is passed as a C
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
13 pointer, bytes objects and strings are passed as pointer to the memory block that contains their data ( char* or wchar_t* ). Python integers are passed as the platforms default C int type, their value is masked to fit into the C type.

Trước khi gọi hàm với các loại tham số khác, chúng ta phải tìm hiểu thêm về các loại dữ liệu

Các kiểu dữ liệu cơ bản

định nghĩa một số kiểu dữ liệu tương thích C nguyên thủy

loại ctypes

loại C

loại trăn

_Bool

bo bo (1)

than

đối tượng byte 1 ký tự

wchar_t

chuỗi 1 ký tự

than

int

không dấu ký tự

int

ngắn ngủi

int

không dấu ngắn

int

int

int

không dấu int

int

Dài

int

không dấu dài

int

__int64 hoặc dài dài

int

không dấu __int64 hoặc không dấu dài long

int

size_t

int

ssize_t hoặc

int

trôi nổi

trôi nổi

gấp đôi

trôi nổi

dài gấp đôi

trôi nổi

char* (NUL chấm dứt)

đối tượng byte hoặc

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
14

wchar_t* (NUL chấm dứt)

chuỗi hoặc

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
14

khoảng trống*

int hoặc

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
14

  1. Hàm tạo chấp nhận bất kỳ đối tượng nào có giá trị thật

Tất cả các loại này có thể được tạo bằng cách gọi chúng bằng một trình khởi tạo tùy chọn đúng loại và giá trị

>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>

Vì các loại này có thể thay đổi, giá trị của chúng cũng có thể được thay đổi sau đó

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
0

Gán một giá trị mới cho các thể hiện của các loại con trỏ , và thay đổi vị trí bộ nhớ mà chúng trỏ tới, không phải nội dung của khối bộ nhớ (tất nhiên là không, vì các đối tượng byte trong Python là bất biến)

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
1

Tuy nhiên, bạn nên cẩn thận, không chuyển chúng đến các hàm mong đợi con trỏ tới bộ nhớ có thể thay đổi. If you need mutable memory blocks, ctypes has a function which creates these in various ways. Nội dung khối bộ nhớ hiện tại có thể được truy cập (hoặc thay đổi) bằng thuộc tính

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
55;

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
2

Hàm thay thế hàm

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
58 cũ (vẫn có sẵn dưới dạng bí danh). Để tạo khối bộ nhớ có thể thay đổi chứa các ký tự unicode thuộc loại C wchar_t , hãy sử dụng hàm.

Chức năng gọi, tiếp tục

Lưu ý rằng printf in ra kênh đầu ra tiêu chuẩn thực chứ không phải , vì vậy những ví dụ này sẽ chỉ hoạt động tại dấu nhắc bảng điều khiển, không phải từ bên trong IDLE hoặc PythonWin

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
3

As has been mentioned before, all Python types except integers, strings, and bytes objects have to be wrapped in their corresponding type, so that they can be converted to the required C data type

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
4

Gọi hàm matrixdic

Trên nhiều nền tảng, việc gọi các hàm biến đổi thông qua ctypes hoàn toàn giống như gọi các hàm với một số tham số cố định. Trên một số nền tảng và đặc biệt là ARM64 dành cho Nền tảng Apple, quy ước gọi hàm biến đổi khác với quy ước gọi hàm thông thường

Trên các nền tảng đó, bắt buộc phải chỉ định thuộc tính argtypes cho các đối số hàm thông thường, không biến đổi

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
5

Bởi vì việc chỉ định thuộc tính không ngăn cản tính di động, nên luôn chỉ định

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
62 cho tất cả các hàm biến đổi

Calling functions with your own custom data types

You can also customize argument conversion to allow instances of your own classes be used as function arguments. looks for an

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
65 attribute and uses this as the function argument. Of course, it must be one of integer, string, or bytes

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
6

If you don’t want to store the instance’s data in the

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
65 instance variable, you could define a which makes the attribute available on request

Specifying the required argument types (function prototypes)

It is possible to specify the required argument types of functions exported from DLLs by setting the

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
62 attribute

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
62 must be a sequence of C data types (the
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
70 function is probably not a good example here, because it takes a variable number and different types of parameters depending on the format string, on the other hand this is quite handy to experiment with this feature)

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
7

Specifying a format protects against incompatible argument types (just as a prototype for a C function), and tries to convert the arguments to valid types

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
8

If you have defined your own classes which you pass to function calls, you have to implement a

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
71 class method for them to be able to use them in the
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
62 sequence. The
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
71 class method receives the Python object passed to the function call, it should do a typecheck or whatever is needed to make sure this object is acceptable, and then return the object itself, its
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
65 attribute, or whatever you want to pass as the C function argument in this case. Again, the result should be an integer, string, bytes, a instance, or an object with an
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
65 attribute

Return types

By default functions are assumed to return the C int type. Other return types can be specified by setting the

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
77 attribute of the function object.

Here is a more advanced example, it uses the

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
78 function, which expects a string pointer and a char, and returns a pointer to a string

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
9

If you want to avoid the

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
79 calls above, you can set the
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
62 attribute, and the second argument will be converted from a single character Python bytes object into a C char

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
0

You can also use a callable Python object (a function or a class for example) as the

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
77 attribute, if the foreign function returns an integer. The callable will be called with the integer the C function returns, and the result of this call will be used as the result of your function call. This is useful to check for error return values and automatically raise an exception

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
1

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
82 is a function which will call Windows
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
83 api to get the string representation of an error code, and returns an exception.
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
82 takes an optional error code parameter, if no one is used, it calls to retrieve it

Please note that a much more powerful error checking mechanism is available through the

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
86 attribute; see the reference manual for details

Passing pointers (or. passing parameters by reference)

Sometimes a C api function expects a pointer to a data type as parameter, probably to write into the corresponding location, or if the data is too large to be passed by value. This is also known as passing parameters by reference

exports the function which is used to pass parameters by reference. The same effect can be achieved with the function, although does a lot more work since it constructs a real pointer object, so it is faster to use if you don’t need the pointer object in Python itself

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
2

Structures and unions

Structures and unions must derive from the and base classes which are defined in the module. Each subclass must define a

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
95 attribute.
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
95 must be a list of 2-tuples, containing a field name and a field type

The field type must be a type like , or any other derived type. structure, union, array, pointer

Here is a simple example of a POINT structure, which contains two integers named x and y, and also shows how to initialize a structure in the constructor

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
3

You can, however, build much more complicated structures. A structure can itself contain other structures by using a structure as a field type

Here is a RECT structure which contains two POINTs named upperleft and lowerright

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
4

Nested structures can also be initialized in the constructor in several ways

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
5

Field s can be retrieved from the class, they are useful for debugging because they can provide useful information

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
6

Warning

does not support passing unions or structures with bit-fields to functions by value. While this may work on 32-bit x86, it’s not guaranteed by the library to work in the general case. Unions and structures with bit-fields should always be passed to functions by pointer

Structure/union alignment and byte order

By default, Structure and Union fields are aligned in the same way the C compiler does it. It is possible to override this behavior by specifying a

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
01 class attribute in the subclass definition. This must be set to a positive integer and specifies the maximum alignment for the fields. This is what
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
02 also does in MSVC

uses the native byte order for Structures and Unions. To build structures with non-native byte order, you can use one of the , , , and base classes. These classes cannot contain pointer fields

Bit fields in structures and unions

It is possible to create structures and unions containing bit fields. Bit fields are only possible for integer fields, the bit width is specified as the third item in the

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
95 tuples

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
7

Arrays

Arrays are sequences, containing a fixed number of instances of the same type

The recommended way to create array types is by multiplying a data type with a positive integer

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
8

Here is an example of a somewhat artificial data type, a structure containing 4 POINTs among other stuff

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
9

Instances are created in the usual way, by calling the class

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
0

The above code print a series of

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
09 lines, because the array contents is initialized to zeros

Initializers of the correct type can also be specified

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
1

Pointers

Pointer instances are created by calling the function on a type

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
2

Pointer instances have a attribute which returns the object to which the pointer points, the

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
13 object above

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
3

Note that does not have OOR (original object return), it constructs a new, equivalent object each time you retrieve an attribute

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
4

Assigning another instance to the pointer’s contents attribute would cause the pointer to point to the memory location where this is stored

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
5

Pointer instances can also be indexed with integers

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
6

Assigning to an integer index changes the pointed to value

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
7

It is also possible to use indexes different from 0, but you must know what you’re doing, just as in C. You can access or change arbitrary memory locations. Nói chung, bạn chỉ sử dụng tính năng này nếu bạn nhận được một con trỏ từ hàm C và bạn biết rằng con trỏ thực sự trỏ đến một mảng thay vì một mục đơn lẻ

Behind the scenes, the function does more than simply create pointer instances, it has to create pointer types first. This is done with the function, which accepts any type, and returns a new type

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
8

Calling the pointer type without an argument creates a

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
13 pointer.
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
13 pointers have a
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
21 boolean value

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
9

checks for

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
13 when dereferencing pointers (but dereferencing invalid non-
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
13 pointers would crash Python)

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
0

Type conversions

Usually, ctypes does strict type checking. This means, if you have

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
25 in the
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
62 list of a function or as the type of a member field in a structure definition, only instances of exactly the same type are accepted. There are some exceptions to this rule, where ctypes accepts other objects. For example, you can pass compatible array instances instead of pointer types. So, for
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
25, ctypes accepts an array of c_int

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
1

In addition, if a function argument is explicitly declared to be a pointer type (such as

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
25) in
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
62, an object of the pointed type (
>>> windll.kernel32.GetModuleHandleA(32)  
Traceback (most recent call last):
  File "", line 1, in 
OSError: exception: access violation reading 0x00000020
>>>
3 in this case) can be passed to the function. ctypes will apply the required conversion in this case automatically

To set a POINTER type field to

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
13, you can assign
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
14

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
2

Sometimes you have instances of incompatible types. In C, you can cast one type into another type. provides a function which can be used in the same way. The

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
36 structure defined above accepts
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
25 pointers or arrays for its
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
39 field, but not instances of other types

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
3

For these cases, the function is handy

The function can be used to cast a ctypes instance into a pointer to a different ctypes data type. takes two parameters, a ctypes object that is or can be converted to a pointer of some kind, and a ctypes pointer type. It returns an instance of the second argument, which references the same memory block as the first argument

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
4

So, can be used to assign to the

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
39 field of
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
36 the structure

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
5

Incomplete Types

Incomplete Types are structures, unions or arrays whose members are not yet specified. In C, they are specified by forward declarations, which are defined later

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
6

The straightforward translation into ctypes code would be this, but it does not work

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
7

because the new

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
46 is not available in the class statement itself. In , we can define the
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
48 class and set the
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
95 attribute later, after the class statement

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
8

Let’s try it. We create two instances of

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
48, and let them point to each other, and finally follow the pointer chain a few times

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
9

Callback functions

allows creating C callable function pointers from Python callables. These are sometimes called callback functions

Trước tiên, bạn phải tạo một lớp cho chức năng gọi lại. The class knows the calling convention, the return type, and the number and types of arguments this function will receive

The factory function creates types for callback functions using the

>>> windll.kernel32.GetModuleHandleA(32)  
Traceback (most recent call last):
  File "", line 1, in 
OSError: exception: access violation reading 0x00000020
>>>
9 calling convention. On Windows, the factory function creates types for callback functions using the
>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>
0 calling convention

Both of these factory functions are called with the result type as first argument, and the callback functions expected argument types as the remaining arguments

I will present an example here which uses the standard C library’s

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
56 function, that is used to sort items with the help of a callback function.
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
56 will be used to sort an array of integers

>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
0

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
56 must be called with a pointer to the data to sort, the number of items in the data array, the size of one item, and a pointer to the comparison function, the callback. Sau đó, cuộc gọi lại sẽ được gọi với hai con trỏ tới các mục và nó phải trả về một số nguyên âm nếu mục đầu tiên nhỏ hơn mục thứ hai, số 0 nếu chúng bằng nhau và một số nguyên dương nếu không

Vì vậy, hàm gọi lại của chúng tôi nhận con trỏ tới số nguyên và phải trả về số nguyên. Đầu tiên chúng ta tạo

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
59 cho chức năng gọi lại

>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
1

Để bắt đầu, đây là một lệnh gọi lại đơn giản hiển thị các giá trị mà nó được truyền

>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
2

Kết quả

>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
3

Now we can actually compare the two items and return a useful result

>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
4

As we can easily check, our array is sorted now

>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
5

Các nhà máy chức năng có thể được sử dụng làm nhà máy trang trí, vì vậy chúng tôi cũng có thể viết

>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
6

Note

Make sure you keep references to objects as long as they are used from C code. không, và nếu bạn không, chúng có thể bị thu gom rác, làm hỏng chương trình của bạn khi gọi lại

Ngoài ra, hãy lưu ý rằng nếu chức năng gọi lại được gọi trong một luồng được tạo bên ngoài sự kiểm soát của Python (e. g. bởi mã nước ngoài gọi hàm gọi lại), ctypes tạo một luồng Python giả mới trên mỗi lệnh gọi. Hành vi này đúng cho hầu hết các mục đích, nhưng điều đó có nghĩa là các giá trị được lưu trữ bằng sẽ không tồn tại qua các lệnh gọi lại khác nhau, ngay cả khi các lệnh gọi đó được thực hiện từ cùng một chuỗi C

Truy cập các giá trị được xuất từ ​​dll

Some shared libraries not only export functions, they also export variables. Một ví dụ trong chính thư viện Python là , một số nguyên được đặt thành 0, 1 hoặc 2, tùy thuộc vào cờ hoặc được cung cấp khi khởi động

can access values like this with the

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
67 class methods of the type. pythonapi là một biểu tượng được xác định trước cấp quyền truy cập vào Python C api

>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
7

Nếu trình thông dịch được bắt đầu bằng , thì mẫu sẽ được in là

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
69 hoặc
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
70 nếu được chỉ định

Một ví dụ mở rộng cũng minh họa việc sử dụng con trỏ truy cập con trỏ được xuất bởi Python

Trích dẫn các tài liệu cho giá trị đó

Con trỏ này được khởi tạo để trỏ đến một mảng các bản ghi, được kết thúc bởi một bản ghi có tất cả các thành viên là

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
13 hoặc 0. Khi một mô-đun bị đóng băng được nhập, nó sẽ được tìm kiếm trong bảng này. Mã của bên thứ ba có thể sử dụng thủ thuật này để cung cấp một bộ sưu tập các mô-đun cố định được tạo động

Vì vậy, thao tác con trỏ này thậm chí có thể hữu ích. To restrict the example size, we show only how this table can be read with

>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
8

Chúng ta đã xác định kiểu dữ liệu, vì vậy chúng ta có thể lấy con trỏ tới bảng

>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
9

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
77 là một ____12_______78 của mảng các bản ghi
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
79, nên chúng ta có thể lặp lại nó, nhưng chúng ta chỉ cần đảm bảo rằng vòng lặp của chúng ta kết thúc, vì con trỏ không có kích thước. Không sớm thì muộn, nó có thể sẽ gặp sự cố do vi phạm quyền truy cập hoặc bất kỳ điều gì tương tự, vì vậy tốt hơn hết là thoát ra khỏi vòng lặp khi chúng tôi nhấn vào mục nhập
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
13

>>> print(libc.time(None))  
1150640792
>>> print(hex(windll.kernel32.GetModuleHandleA(None)))  
0x1d000000
>>>
0

Thực tế là Python tiêu chuẩn có một mô-đun bị đóng băng và một gói bị đóng băng (được biểu thị bởi thành viên

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
81 phủ định) không được biết rõ, nó chỉ được sử dụng để thử nghiệm. Hãy dùng thử với
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
82 chẳng hạn

ngạc nhiên

There are some edges in where you might expect something other than what actually happens

Xem xét ví dụ sau

>>> print(libc.time(None))  
1150640792
>>> print(hex(windll.kernel32.GetModuleHandleA(None)))  
0x1d000000
>>>
1

Hm. We certainly expected the last statement to print

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
84. What happened? Here are the steps of the
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
85 line above

>>> print(libc.time(None))  
1150640792
>>> print(hex(windll.kernel32.GetModuleHandleA(None)))  
0x1d000000
>>>
2

Note that

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
86 and
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
87 are objects still using the internal buffer of the
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
88 object above. So executing
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
89 copies the buffer contents of
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
86 into
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
88 ‘s buffer. Đến lượt nó, điều này thay đổi nội dung của
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
87. Vì vậy, nhiệm vụ cuối cùng
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
93, không có tác dụng như mong đợi

Hãy nhớ rằng việc truy xuất các đối tượng phụ từ Cấu trúc, Liên kết và Mảng không sao chép đối tượng phụ, thay vào đó, nó truy xuất một đối tượng trình bao đang truy cập vào bộ đệm bên dưới của đối tượng gốc

Một ví dụ khác có thể hoạt động khác với những gì người ta mong đợi là đây

>>> print(libc.time(None))  
1150640792
>>> print(hex(windll.kernel32.GetModuleHandleA(None)))  
0x1d000000
>>>
3

Note

Các đối tượng được khởi tạo từ chỉ có thể có giá trị được đặt thành byte hoặc số nguyên

Tại sao nó lại in

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
21? . Lưu trữ một đối tượng Python trong khối bộ nhớ không lưu trữ chính đối tượng đó, thay vào đó,
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
12 của đối tượng được lưu trữ. Truy cập lại nội dung sẽ tạo một đối tượng Python mới mỗi lần

Kiểu dữ liệu có kích thước thay đổi

cung cấp một số hỗ trợ cho các mảng và cấu trúc có kích thước thay đổi

Chức năng này có thể được sử dụng để thay đổi kích thước bộ nhớ đệm của một đối tượng ctypes hiện có. Hàm lấy đối tượng làm đối số đầu tiên và kích thước được yêu cầu tính bằng byte làm đối số thứ hai. Không thể tạo khối bộ nhớ nhỏ hơn khối bộ nhớ tự nhiên được chỉ định bởi loại đối tượng, a sẽ tăng nếu điều này được thử

>>> print(libc.time(None))  
1150640792
>>> print(hex(windll.kernel32.GetModuleHandleA(None)))  
0x1d000000
>>>
4

Điều này là tốt và tốt, nhưng làm cách nào để truy cập các phần tử bổ sung có trong mảng này?

>>> print(libc.time(None))  
1150640792
>>> print(hex(windll.kernel32.GetModuleHandleA(None)))  
0x1d000000
>>>
5

Một cách khác để sử dụng các loại dữ liệu có kích thước thay đổi là sử dụng tính chất động của Python và (xác định lại) loại dữ liệu sau khi đã biết kích thước yêu cầu, tùy từng trường hợp

tài liệu tham khảo ctypes

Tìm thư viện dùng chung

Khi lập trình bằng ngôn ngữ được biên dịch, các thư viện dùng chung được truy cập khi biên dịch/liên kết chương trình và khi chương trình được chạy

Mục đích của hàm

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
01 là định vị thư viện theo cách tương tự như những gì trình biên dịch hoặc trình tải thời gian chạy thực hiện (trên các nền tảng có một số phiên bản của thư viện dùng chung, phiên bản mới nhất sẽ được tải), trong khi trình tải thư viện ctypes hoạt động như khi một

Mô-đun

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
02 cung cấp một chức năng có thể giúp xác định thư viện sẽ tải

ctypes. sử dụng. find_library(tên)

Cố gắng tìm thư viện và trả lại tên đường dẫn. name là tên thư viện không có bất kỳ tiền tố nào như lib, hậu tố như

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
03,
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
04 hoặc số phiên bản (đây là biểu mẫu được sử dụng cho tùy chọn trình liên kết posix
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
05). Nếu không tìm thấy thư viện, trả về
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
14

Chức năng chính xác phụ thuộc vào hệ thống

Trên Linux,

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
01 cố chạy các chương trình bên ngoài (
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
08,
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
09,
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
10 và
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
11) để tìm tệp thư viện. Nó trả về tên tệp của tệp thư viện

Đã thay đổi trong phiên bản 3. 6. Trên Linux, giá trị của biến môi trường

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
12 được sử dụng khi tìm kiếm thư viện, nếu không thể tìm thấy thư viện bằng bất kỳ cách nào khác.

Dưới đây là một số ví dụ

>>> print(libc.time(None))  
1150640792
>>> print(hex(windll.kernel32.GetModuleHandleA(None)))  
0x1d000000
>>>
6

Trên macOS,

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
01 thử một số sơ đồ đặt tên và đường dẫn được xác định trước để định vị thư viện và trả về tên đường dẫn đầy đủ nếu thành công

>>> print(libc.time(None))  
1150640792
>>> print(hex(windll.kernel32.GetModuleHandleA(None)))  
0x1d000000
>>>
7

Trên Windows,

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
01 tìm kiếm dọc theo đường dẫn tìm kiếm hệ thống và trả về tên đường dẫn đầy đủ, nhưng vì không có sơ đồ đặt tên được xác định trước nên lệnh gọi như
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
15 sẽ không thành công và trả về
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
14

Nếu gói thư viện dùng chung bằng , có thể tốt hơn là xác định tên thư viện dùng chung tại thời điểm phát triển và mã hóa cứng tên đó vào mô-đun trình bao bọc thay vì sử dụng

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
01 để định vị thư viện khi chạy

Đang tải thư viện dùng chung

Có một số cách để tải các thư viện dùng chung vào quy trình Python. One way is to instantiate one of the following classes

lớp ctypes. CDLL(tên , chế độ=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None)

Các thực thể của lớp này đại diện cho các thư viện dùng chung đã tải. Các hàm trong các thư viện này sử dụng quy ước gọi C tiêu chuẩn và được giả định là trả về int .

Trên Windows, việc tạo một phiên bản có thể không thành công ngay cả khi tên DLL tồn tại. Khi không tìm thấy tệp DLL phụ thuộc của tệp DLL đã tải, lỗi sẽ xuất hiện với thông báo “[WinError 126] Không thể tìm thấy mô-đun được chỉ định”. Thông báo lỗi này không chứa tên của tệp DLL bị thiếu vì API Windows không trả lại thông tin này khiến lỗi này khó chẩn đoán. Để giải quyết lỗi này và xác định không tìm thấy DLL nào, bạn cần tìm danh sách các DLL phụ thuộc và xác định xem không tìm thấy DLL nào bằng cách sử dụng các công cụ theo dõi và gỡ lỗi của Windows

Xem thêm

Microsoft DUMPBIN tool – Một công cụ để tìm DLL phụ thuộc

lớp ctypes. OleDLL(tên , chế độ=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None)

chỉ cửa sổ. Các phiên bản của lớp này đại diện cho các thư viện dùng chung đã tải, các hàm trong các thư viện này sử dụng quy ước gọi ____________0 và được giả định trả về mã cụ thể của cửa sổ. các giá trị chứa thông tin xác định lệnh gọi hàm thất bại hay thành công, cùng với mã lỗi bổ sung. Nếu giá trị trả về báo hiệu lỗi, giá trị sẽ tự động tăng lên

Đã thay đổi trong phiên bản 3. 3. đã từng được nâng lên.

lớp ctypes. WinDLL(tên , chế độ=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None)

Chỉ dành cho Windows. Các thể hiện của lớp này đại diện cho các thư viện dùng chung đã tải, các hàm trong các thư viện này sử dụng quy ước gọi hàm

>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>
0 và được giả định là trả về int theo mặc định.

Python được phát hành trước khi gọi bất kỳ chức năng nào được xuất bởi các thư viện này và được yêu cầu lại sau đó

lớp ctypes. PyDLL(tên , chế độ=DEFAULT_MODE, handle=None)

Các phiên bản của lớp này hoạt động giống như các phiên bản, ngoại trừ GIL Python không được giải phóng trong khi gọi hàm và sau khi thực thi chức năng, cờ lỗi Python được kiểm tra. Nếu cờ lỗi được đặt, một ngoại lệ Python sẽ xuất hiện

Do đó, điều này chỉ hữu ích khi gọi trực tiếp các hàm api của Python C

Tất cả các lớp này có thể được khởi tạo bằng cách gọi chúng với ít nhất một đối số, tên đường dẫn của thư viện dùng chung. Nếu bạn có một điều khiển hiện có cho một thư viện dùng chung đã được tải, thì nó có thể được chuyển dưới dạng tham số có tên

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
28, nếu không, các nền tảng cơ bản hàm
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
29 hoặc
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
30 được sử dụng để tải thư viện vào quy trình và để có một điều khiển cho nó

Tham số chế độ có thể được sử dụng để chỉ định cách tải thư viện. Để biết chi tiết, tham khảo trang dlopen(3). Trên Windows, chế độ bị bỏ qua. Trên các hệ thống posix, RTLD_NOW luôn được thêm vào và không thể định cấu hình

Tham số use_errno, khi được đặt thành true, sẽ bật cơ chế ctypes cho phép truy cập số lỗi hệ thống theo cách an toàn. duy trì một bản sao cục bộ của biến hệ thống;

Hàm trả về giá trị của bản sao riêng của ctypes và hàm thay đổi bản sao riêng của ctypes thành một giá trị mới và trả về giá trị cũ

Tham số use_last_error, khi được đặt thành true, sẽ bật cơ chế tương tự cho mã lỗi Windows được quản lý bởi và

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
39 Hàm Windows API;

Tham số winmode được sử dụng trên Windows để chỉ định cách thư viện được tải (vì chế độ bị bỏ qua). Nó nhận bất kỳ giá trị nào hợp lệ cho tham số cờ

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
42 API Win32. Khi bị bỏ qua, mặc định là sử dụng các cờ dẫn đến tải DLL an toàn nhất để tránh các sự cố như chiếm quyền điều khiển DLL. Chuyển đường dẫn đầy đủ tới DLL là cách an toàn nhất để đảm bảo tải đúng thư viện và các phụ thuộc

Đã thay đổi trong phiên bản 3. 8. Đã thêm tham số winmode.

ctypes. RTLD_GLOBAL

Gắn cờ để sử dụng làm tham số chế độ. Trên các nền tảng không có cờ này, nó được định nghĩa là số nguyên 0

ctypes. RTLD_LOCAL

Gắn cờ để sử dụng làm tham số chế độ. Trên các nền tảng không có tính năng này, nó giống như RTLD_GLOBAL

ctypes. DEFAULT_MODE

Chế độ mặc định được sử dụng để tải các thư viện dùng chung. Trên OSX10. 3, đây là RTLD_GLOBAL, nếu không thì nó giống như RTLD_LOCAL

Thể hiện của các lớp này không có phương thức công khai. Các chức năng được xuất bởi thư viện dùng chung có thể được truy cập dưới dạng thuộc tính hoặc theo chỉ mục. Xin lưu ý rằng việc truy cập hàm thông qua một thuộc tính sẽ lưu trữ kết quả và do đó, việc truy cập nó nhiều lần sẽ trả về cùng một đối tượng mỗi lần. Mặt khác, truy cập nó thông qua một chỉ mục sẽ trả về một đối tượng mới mỗi lần

>>> print(libc.time(None))  
1150640792
>>> print(hex(windll.kernel32.GetModuleHandleA(None)))  
0x1d000000
>>>
8

Các thuộc tính công khai sau đây khả dụng, tên của chúng bắt đầu bằng dấu gạch dưới để không xung đột với tên hàm đã xuất

PyDLL. _xử lý

Tay cầm hệ thống dùng để truy cập thư viện

PyDLL. _tên

The name of the library passed in the constructor

Các thư viện dùng chung cũng có thể được tải bằng cách sử dụng một trong các đối tượng đúc sẵn, là các thể hiện của lớp, bằng cách gọi phương thức

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
00 hoặc bằng cách truy xuất thư viện dưới dạng thuộc tính của thể hiện trình tải

lớp ctypes. Trình tải thư viện(dlltype)

Lớp tải thư viện dùng chung. dlltype phải là một trong các loại , , hoặc

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
49 có hành vi đặc biệt. Nó cho phép tải một thư viện dùng chung bằng cách truy cập nó dưới dạng thuộc tính của một phiên bản trình tải thư viện. Kết quả được lưu trong bộ nhớ cache, do đó, các truy cập thuộc tính lặp lại sẽ trả về cùng một thư viện mỗi lần

LoadLibrary(tên)

Tải thư viện dùng chung vào quy trình và trả lại. Phương thức này luôn trả về một thể hiện mới của thư viện

Những bộ tải thư viện đúc sẵn này có sẵn

ctypes. cdll

Tạo phiên bản

ctypes. gió

chỉ cửa sổ. Tạo phiên bản

ctypes. oledll

chỉ cửa sổ. Tạo phiên bản

ctypes. pydll

Tạo phiên bản

Để truy cập trực tiếp vào api C Python, có sẵn đối tượng thư viện chia sẻ Python sẵn sàng sử dụng

ctypes. pythonapi

Một phiên bản hiển thị các hàm API Python C dưới dạng thuộc tính. Lưu ý rằng tất cả các hàm này được giả định là trả về C int , điều này tất nhiên không phải lúc nào cũng đúng, vì vậy bạn phải gán đúng thuộc tính

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
77 để sử dụng .

Loading a library through any of these objects raises an

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
56 with string argument
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
57, the name used to load the library

Việc truy cập một hàm trên thư viện đã tải sẽ làm phát sinh sự kiện kiểm tra

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
58 với các đối số
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
59 (đối tượng thư viện) và
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
57 (tên của ký hiệu dưới dạng chuỗi hoặc số nguyên)

Trong trường hợp khi chỉ có thẻ điều khiển thư viện chứ không phải đối tượng, việc truy cập một hàm sẽ tạo ra sự kiện kiểm tra

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
61 với các đối số
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
28 (xử lý thư viện thô) và
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
57

chức năng nước ngoài

Như đã giải thích trong phần trước, các chức năng nước ngoài có thể được truy cập dưới dạng thuộc tính của các thư viện dùng chung đã tải. The function objects created in this way by default accept any number of arguments, accept any ctypes data instances as arguments, and return the default result type specified by the library loader. They are instances of a private class

class ctypes. _FuncPtr

Base class for C callable foreign functions

Instances of foreign functions are also C compatible data types; they represent C function pointers

This behavior can be customized by assigning to special attributes of the foreign function object

restype

Assign a ctypes type to specify the result type of the foreign function. Use

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
14 for void , a function not returning anything.

It is possible to assign a callable Python object that is not a ctypes type, in this case the function is assumed to return a C int , and the callable will be called with this integer, allowing further processing or error checking. Using this is deprecated, for more flexible post processing or error checking use a ctypes data type as and assign a callable to the attribute.

argtypes

Assign a tuple of ctypes types to specify the argument types that the function accepts. Functions using the

>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>
0 calling convention can only be called with the same number of arguments as the length of this tuple; functions using the C calling convention accept additional, unspecified arguments as well

When a foreign function is called, each actual argument is passed to the

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
71 class method of the items in the tuple, this method allows adapting the actual argument to an object that the foreign function accepts. For example, a item in the tuple will convert a string passed as argument into a bytes object using ctypes conversion rules

New. It is now possible to put items in argtypes which are not ctypes types, but each item must have a

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
71 method which returns a value usable as argument (integer, string, ctypes instance). This allows defining adapters that can adapt custom objects as function parameters

errcheck

Assign a Python function or another callable to this attribute. The callable will be called with three or more arguments

callable(result , func , arguments)

result is what the foreign function returns, as specified by the

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
77 attribute

func is the foreign function object itself, this allows reusing the same callable object to check or post process the results of several functions

arguments is a tuple containing the parameters originally passed to the function call, this allows specializing the behavior on the arguments used

The object that this function returns will be returned from the foreign function call, but it can also check the result value and raise an exception if the foreign function call failed

exception ctypes. ArgumentError

This exception is raised when a foreign function call cannot convert one of the passed arguments

On Windows, when a foreign function call raises a system exception (for example, due to an access violation), it will be captured and replaced with a suitable Python exception. Further, an auditing event

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
74 with argument
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
75 will be raised, allowing an audit hook to replace the exception with its own

Some ways to invoke foreign function calls may raise an auditing event

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
76 with arguments
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
77 and
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
78

Function prototypes

Foreign functions can also be created by instantiating function prototypes. Function prototypes are similar to function prototypes in C; they describe a function (return type, argument types, calling convention) without defining an implementation. The factory functions must be called with the desired result type and the argument types of the function, and can be used as decorator factories, and as such, be applied to functions through the

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
79 syntax. Xem ví dụ

ctypes. CFUNCTYPE(restype , *argtypes , use_errno=False , use_last_error=False)

The returned function prototype creates functions that use the standard C calling convention. The function will release the GIL during the call. If use_errno is set to true, the ctypes private copy of the system variable is exchanged with the real value before and after the call; use_last_error does the same for the Windows error code

ctypes. WINFUNCTYPE(restype , *argtypes , use_errno=False , use_last_error=False)

Windows only. The returned function prototype creates functions that use the

>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>
0 calling convention. The function will release the GIL during the call. use_errno and use_last_error have the same meaning as above

ctypes. PYFUNCTYPE(restype , *argtypes)

The returned function prototype creates functions that use the Python calling convention. The function will not release the GIL during the call

Function prototypes created by these factory functions can be instantiated in different ways, depending on the type and number of the parameters in the call

prototype(address)

Returns a foreign function at the specified address which must be an integer

prototype(callable)

Create a C callable function (a callback function) from a Python callable

prototype(func_spec[ , paramflags])

Returns a foreign function exported by a shared library. func_spec must be a 2-tuple

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
83. The first item is the name of the exported function as string, or the ordinal of the exported function as small integer. The second item is the shared library instance

prototype(vtbl_index , name[ , paramflags[ , iid]])

Returns a foreign function that will call a COM method. vtbl_index is the index into the virtual function table, a small non-negative integer. name is name of the COM method. iid is an optional pointer to the interface identifier which is used in extended error reporting

COM methods use a special calling convention. They require a pointer to the COM interface as first argument, in addition to those parameters that are specified in the

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
62 tuple

The optional paramflags parameter creates foreign function wrappers with much more functionality than the features described above

paramflags must be a tuple of the same length as

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
62

Each item in this tuple contains further information about a parameter, it must be a tuple containing one, two, or three items

The first item is an integer containing a combination of direction flags for the parameter

1

Specifies an input parameter to the function

2

Output parameter. The foreign function fills in a value

4

Input parameter which defaults to the integer zero

The optional second item is the parameter name as string. If this is specified, the foreign function can be called with named parameters

The optional third item is the default value for this parameter

This example demonstrates how to wrap the Windows

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
86 function so that it supports default parameters and named arguments. The C declaration from the windows header file is this

>>> print(libc.time(None))  
1150640792
>>> print(hex(windll.kernel32.GetModuleHandleA(None)))  
0x1d000000
>>>
9

Here is the wrapping with

>>> cdll.kernel32.GetModuleHandleA(None)  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>

>>> windll.msvcrt.printf(b"spam")  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>
0

The

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
88 foreign function can now be called in these ways

>>> cdll.kernel32.GetModuleHandleA(None)  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>

>>> windll.msvcrt.printf(b"spam")  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>
1

Một ví dụ thứ hai minh họa các tham số đầu ra. Hàm win32

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
89 truy xuất kích thước của một cửa sổ đã chỉ định bằng cách sao chép chúng vào cấu trúc
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
90 mà người gọi phải cung cấp. Đây là khai báo C

>>> cdll.kernel32.GetModuleHandleA(None)  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>

>>> windll.msvcrt.printf(b"spam")  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>
2

Here is the wrapping with

>>> cdll.kernel32.GetModuleHandleA(None)  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>

>>> windll.msvcrt.printf(b"spam")  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>
3

Các hàm có tham số đầu ra sẽ tự động trả về giá trị tham số đầu ra nếu có một giá trị duy nhất hoặc một bộ chứa các giá trị tham số đầu ra khi có nhiều hơn một giá trị, do đó, hàm GetWindowRect hiện trả về một phiên bản RECT khi được gọi

Các tham số đầu ra có thể được kết hợp với giao thức

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
86 để thực hiện thêm quá trình xử lý đầu ra và kiểm tra lỗi. Hàm api win32
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
89 trả về một
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
94 để báo hiệu thành công hay thất bại, vì vậy hàm này có thể thực hiện kiểm tra lỗi và đưa ra một ngoại lệ khi lệnh gọi api không thành công

>>> cdll.kernel32.GetModuleHandleA(None)  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>

>>> windll.msvcrt.printf(b"spam")  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>
4

Nếu hàm

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
86 trả về bộ đối số mà nó nhận được không thay đổi, tiếp tục quá trình xử lý bình thường mà nó thực hiện trên các tham số đầu ra. Nếu bạn muốn trả về một bộ tọa độ cửa sổ thay vì một phiên bản
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
90, bạn có thể truy xuất các trường trong hàm và trả lại chúng, quá trình xử lý thông thường sẽ không diễn ra nữa

>>> cdll.kernel32.GetModuleHandleA(None)  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>

>>> windll.msvcrt.printf(b"spam")  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>
5

Các chức năng tiện ích

ctypes. địa chỉ của(obj)

Trả về địa chỉ của bộ nhớ đệm dưới dạng số nguyên. obj phải là một thể hiện của kiểu ctypes

Tăng một

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
98 với đối số
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
99

ctypes. căn chỉnh(obj_or_type)

Trả về các yêu cầu căn chỉnh của một loại ctypes. obj_or_type phải là loại ctypes hoặc thể hiện

ctypes. byref(obj[ , offset])

Trả về một con trỏ light-weight cho obj, con trỏ này phải là một thể hiện của kiểu ctypes. offset mặc định bằng 0 và phải là số nguyên sẽ được thêm vào giá trị con trỏ bên trong

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
00 tương ứng với mã C này

>>> cdll.kernel32.GetModuleHandleA(None)  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>

>>> windll.msvcrt.printf(b"spam")  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>
6

Đối tượng được trả về chỉ có thể được sử dụng làm tham số gọi hàm nước ngoài. Nó hoạt động tương tự như

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
01, nhưng quá trình xây dựng nhanh hơn rất nhiều

ctypes. truyền(đối tượng , loại)

Hàm này tương tự như toán tử ép kiểu trong C. Nó trả về một phiên bản mới của loại trỏ đến cùng một khối bộ nhớ như obj. loại phải là loại con trỏ và obj phải là đối tượng có thể được hiểu là con trỏ

ctypes. create_string_buffer(init_or_size , size=None)

Hàm này tạo bộ đệm ký tự có thể thay đổi. Đối tượng được trả về là một mảng ctypes của

init_or_size phải là một số nguyên chỉ định kích thước của mảng hoặc một đối tượng byte sẽ được sử dụng để khởi tạo các mục mảng

Nếu một đối tượng byte được chỉ định làm đối số đầu tiên, thì bộ đệm được tạo một mục lớn hơn độ dài của nó để phần tử cuối cùng trong mảng là ký tự kết thúc NUL. Một số nguyên có thể được truyền dưới dạng đối số thứ hai, cho phép chỉ định kích thước của mảng nếu không nên sử dụng độ dài của byte

Nâng cao một

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
03 với các đối số
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
04,
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
81

ctypes. create_unicode_buffer(init_or_size , size=None)

Hàm này tạo bộ đệm ký tự unicode có thể thay đổi. Đối tượng được trả về là một mảng ctypes của

init_or_size phải là một số nguyên chỉ định kích thước của mảng hoặc một chuỗi sẽ được sử dụng để khởi tạo các mục mảng

Nếu một chuỗi được chỉ định làm đối số đầu tiên, bộ đệm được tạo một mục lớn hơn độ dài của chuỗi sao cho phần tử cuối cùng trong mảng là ký tự kết thúc NUL. Một số nguyên có thể được truyền dưới dạng đối số thứ hai, cho phép chỉ định kích thước của mảng nếu không nên sử dụng độ dài của chuỗi

Nâng cao một

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
07 với các đối số
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
04,
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
81

ctypes. DllCanUnloadNow()

chỉ cửa sổ. This function is a hook which allows implementing in-process COM servers with ctypes. Nó được gọi từ hàm DllCanUnloadNow mà dll mở rộng _ctypes xuất

ctypes. DllGetClassObject()

chỉ cửa sổ. Chức năng này là một hook cho phép triển khai các máy chủ COM đang xử lý với ctypes. Nó được gọi từ hàm DllGetClassObject mà dll mở rộng

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
10 xuất

ctypes. sử dụng. find_library(tên)

Cố gắng tìm thư viện và trả lại tên đường dẫn. name là tên thư viện không có tiền tố như

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
11, hậu tố như
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
03,
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
04 hoặc số phiên bản (đây là biểu mẫu được sử dụng cho tùy chọn trình liên kết posix
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
05). If no library can be found, returns
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
14

Chức năng chính xác phụ thuộc vào hệ thống

ctypes. sử dụng. find_msvcrt()

chỉ cửa sổ. trả lại tên tệp của thư viện thời gian chạy VC được sử dụng bởi Python và bởi các mô-đun mở rộng. Nếu tên của thư viện không thể được xác định, thì trả về

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
14

Ví dụ: nếu bạn cần giải phóng bộ nhớ, được cấp phát bởi một mô-đun mở rộng bằng lệnh gọi tới

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
17, thì điều quan trọng là bạn phải sử dụng hàm trong cùng thư viện đã cấp phát bộ nhớ

ctypes. Lỗi định dạng([])

chỉ cửa sổ. Trả về mô tả bằng văn bản của mã mã lỗi. Nếu không có mã lỗi nào được chỉ định, mã lỗi cuối cùng được sử dụng bằng cách gọi hàm api Windows GetLastError

ctypes. GetLastError()

chỉ cửa sổ. Trả về mã lỗi cuối cùng do Windows đặt trong chuỗi cuộc gọi. Chức năng này gọi trực tiếp chức năng Windows

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
85, nó không trả về bản sao mã lỗi ctypes-private

ctypes. get_errno()

Trả về giá trị hiện tại của bản sao ctypes-private của biến hệ thống trong luồng gọi

Tăng một

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
20 mà không có đối số

ctypes. get_last_error()

chỉ cửa sổ. trả về giá trị hiện tại của biến ctypes-private của hệ thống

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
21 trong luồng gọi

Tăng một

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
22 mà không có đối số

ctypes. memmove(dst , src, count)

Giống như chức năng thư viện C memmove tiêu chuẩn. bản sao đếm byte từ src đến dst. dst và src phải là các trường hợp số nguyên hoặc ctypes có thể được chuyển đổi thành con trỏ

ctypes. bộ nhớ(dst , c, count)

Giống như chức năng thư viện bộ nhớ C tiêu chuẩn. lấp đầy khối bộ nhớ tại địa chỉ dst với số byte giá trị c. dst phải là một số nguyên chỉ định một địa chỉ hoặc một phiên bản ctypes

ctypes. POINTER(loại)

Hàm xuất xưởng này tạo và trả về một loại con trỏ ctypes mới. Các loại con trỏ được lưu vào bộ nhớ cache và được sử dụng lại trong nội bộ, vì vậy việc gọi hàm này nhiều lần sẽ rẻ. loại phải là loại ctypes

ctypes. con trỏ(obj)

Hàm này tạo một thể hiện con trỏ mới, trỏ tới obj. Đối tượng được trả về thuộc loại

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
23

Ghi chú. Nếu bạn chỉ muốn chuyển một con trỏ tới một đối tượng cho một lệnh gọi hàm lạ, bạn nên sử dụng

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
24 sẽ nhanh hơn nhiều

ctypes. thay đổi kích thước(obj , kích thước)

Hàm này thay đổi kích thước bộ đệm bộ nhớ trong của obj, đây phải là một phiên bản của loại ctypes. Không thể làm cho bộ đệm nhỏ hơn kích thước gốc của loại đối tượng, như được đưa ra bởi

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
25, nhưng có thể phóng to bộ đệm

ctypes. set_errno(giá trị)

Đặt giá trị hiện tại của bản sao ctypes-private của biến hệ thống trong luồng gọi thành giá trị và trả về giá trị trước đó

Đưa ra một

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
27 với lập luận
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
31

ctypes. set_last_error(giá trị)

chỉ cửa sổ. đặt giá trị hiện tại của biến ctypes-private của hệ thống

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
21 trong luồng gọi thành giá trị và trả về giá trị trước đó

Tăng một

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
30 với lập luận
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
31

ctypes. sizeof(obj_or_type)

Trả về kích thước tính bằng byte của loại ctypes hoặc bộ đệm bộ nhớ thể hiện. Có giống như toán tử C

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
32

ctypes. string_at(địa chỉ , kích thước=- 1)

Hàm này trả về chuỗi C bắt đầu tại địa chỉ địa chỉ bộ nhớ dưới dạng đối tượng byte. Nếu kích thước được chỉ định, thì nó được sử dụng làm kích thước, nếu không thì chuỗi được coi là không kết thúc

Nâng cao một

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
33 với các đối số
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
34,
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
81

ctypes. WinError(=Không, descr=None)

chỉ cửa sổ. chức năng này có lẽ là thứ tồi tệ nhất trong ctypes. Nó tạo ra một thể hiện của OSError. Nếu mã không được chỉ định,

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
36 được gọi để xác định mã lỗi. Nếu descr không được chỉ định, được gọi để nhận mô tả bằng văn bản về lỗi

Đã thay đổi trong phiên bản 3. 3. An instance of used to be created.

ctypes. wstring_at(address , size=- 1)

Hàm này trả về chuỗi ký tự rộng bắt đầu từ địa chỉ địa chỉ bộ nhớ dưới dạng chuỗi. Nếu kích thước được chỉ định, thì nó được sử dụng làm số ký tự của chuỗi, nếu không thì chuỗi được coi là không kết thúc

Nâng cao một

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
39 với các đối số
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
34,
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
81

Loại dữ liệu

lớp ctypes. _CData

Lớp không công khai này là lớp cơ sở chung của tất cả các kiểu dữ liệu ctypes. Trong số những thứ khác, tất cả các phiên bản loại ctypes chứa một khối bộ nhớ chứa dữ liệu tương thích với C; . Một biến thể hiện khác được hiển thị là ;

Các phương thức phổ biến của các kiểu dữ liệu ctypes, đây đều là các phương thức của lớp (chính xác là chúng là các phương thức của lớp)

from_buffer(nguồn[ , offset])

Phương thức này trả về một thể hiện ctypes chia sẻ bộ đệm của đối tượng nguồn. Đối tượng nguồn phải hỗ trợ giao diện bộ đệm có thể ghi. Tham số offset tùy chọn chỉ định một offset vào bộ đệm nguồn theo byte; . Nếu bộ đệm nguồn không đủ lớn thì a được nâng lên

Nâng cao một

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
45 với các đối số
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
78,
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
81,
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
48

from_buffer_copy(nguồn[ , offset])

Phương thức này tạo một thể hiện ctypes, sao chép bộ đệm từ bộ đệm đối tượng nguồn phải có thể đọc được. Tham số offset tùy chọn chỉ định một offset vào bộ đệm nguồn theo byte; . Nếu bộ đệm nguồn không đủ lớn thì a được nâng lên

Nâng cao một

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
45 với các đối số
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
78,
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
81,
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
48

from_address(địa chỉ)

Phương thức này trả về một thể hiện kiểu ctypes sử dụng bộ nhớ được chỉ định bởi địa chỉ phải là một số nguyên

Phương thức này và các phương thức khác gián tiếp gọi phương thức này, đưa ra một

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
54 với đối số
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
34

from_param(obj)

Phương pháp này điều chỉnh obj thành loại ctypes. Nó được gọi với đối tượng thực tế được sử dụng trong lệnh gọi hàm ngoại khi loại có trong bộ dữ liệu

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
62 của hàm ngoại;

Tất cả các kiểu dữ liệu ctypes đều có triển khai mặc định của phương thức lớp này thường trả về obj nếu đó là một thể hiện của kiểu. Một số loại cũng chấp nhận các đối tượng khác

in_dll(thư viện , tên)

Phương thức này trả về một thể hiện kiểu ctypes được xuất bởi một thư viện dùng chung. tên là tên của biểu tượng xuất dữ liệu, thư viện là thư viện được chia sẻ đã tải

Các biến thể hiện phổ biến của kiểu dữ liệu ctypes

_b_base_

Đôi khi các phiên bản dữ liệu ctypes không sở hữu khối bộ nhớ mà chúng chứa, thay vào đó chúng chia sẻ một phần khối bộ nhớ của một đối tượng cơ sở. Thành viên chỉ đọc là đối tượng ctypes gốc sở hữu khối bộ nhớ

_b_needsfree_

Biến chỉ đọc này là đúng khi cá thể dữ liệu ctypes đã tự cấp phát khối bộ nhớ, ngược lại là sai

_các đối tượng

Thành viên này là

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
14 hoặc một từ điển chứa các đối tượng Python cần được duy trì để nội dung khối bộ nhớ được giữ hợp lệ. Đối tượng này chỉ được hiển thị để gỡ lỗi;

Các kiểu dữ liệu cơ bản

lớp ctypes. _SimpleCData

Lớp không công khai này là lớp cơ sở của tất cả các kiểu dữ liệu ctypes cơ bản. Nó được đề cập ở đây vì nó chứa các thuộc tính chung của các kiểu dữ liệu ctypes cơ bản. là một lớp con của , vì vậy nó kế thừa các phương thức và thuộc tính của chúng. các loại dữ liệu ctypes không và không chứa con trỏ giờ đây có thể được chọn

Các trường hợp có một thuộc tính duy nhất

giá trị

Thuộc tính này chứa giá trị thực của thể hiện. Đối với các loại số nguyên và con trỏ, nó là một số nguyên, đối với các loại ký tự, nó là một đối tượng hoặc chuỗi byte ký tự đơn, đối với các loại con trỏ ký tự, nó là một đối tượng hoặc chuỗi byte Python

Khi thuộc tính

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
56 được truy xuất từ ​​một phiên bản ctypes, thường thì một đối tượng mới được trả về mỗi lần. không thực hiện trả về đối tượng ban đầu, luôn luôn tạo đối tượng mới. Điều này cũng đúng với tất cả các trường hợp đối tượng ctypes khác

Các kiểu dữ liệu cơ bản, khi được trả về dưới dạng kết quả gọi hàm ngoại, hoặc, ví dụ, bằng cách truy xuất các thành viên trường cấu trúc hoặc các mục mảng, được chuyển đổi rõ ràng thành các kiểu Python gốc. Nói cách khác, nếu một hàm nước ngoài có

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
77 của , bạn sẽ luôn nhận được một đối tượng byte Python, không phải là một thể hiện

Các lớp con của các kiểu dữ liệu cơ bản không kế thừa hành vi này. Vì vậy, nếu một hàm nước ngoài

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
77 là một lớp con của , bạn sẽ nhận được một thể hiện của lớp con này từ lời gọi hàm. Tất nhiên, bạn có thể lấy giá trị của con trỏ bằng cách truy cập thuộc tính
>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
56

Đây là những kiểu dữ liệu ctypes cơ bản

lớp ctypes. c_byte

Đại diện cho kiểu dữ liệu C signed char và diễn giải giá trị dưới dạng số nguyên nhỏ. Hàm tạo chấp nhận một trình khởi tạo số nguyên tùy chọn; .

lớp ctypes. c_char

Đại diện cho kiểu dữ liệu C char và diễn giải giá trị dưới dạng một ký tự. Hàm tạo chấp nhận một trình khởi tạo chuỗi tùy chọn, độ dài của chuỗi phải chính xác là một ký tự.

lớp ctypes. c_char_p

Đại diện cho kiểu dữ liệu C char* khi nó trỏ đến một chuỗi có tận cùng bằng 0. Đối với con trỏ ký tự chung cũng có thể trỏ đến dữ liệu nhị phân, phải sử dụng ____________69. Hàm tạo chấp nhận một địa chỉ số nguyên hoặc đối tượng byte.

lớp ctypes. c_double

Đại diện cho kiểu dữ liệu C double . Hàm tạo chấp nhận một trình khởi tạo float tùy chọn.

lớp ctypes. c_longdouble

Đại diện cho kiểu dữ liệu C long double . Hàm tạo chấp nhận một trình khởi tạo float tùy chọn. Trên các nền tảng có

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
70, đó là bí danh của.

lớp ctypes. c_float

Đại diện cho kiểu dữ liệu C float . Hàm tạo chấp nhận một trình khởi tạo float tùy chọn.

lớp ctypes. c_int

Đại diện cho kiểu dữ liệu C signed int . Hàm tạo chấp nhận một trình khởi tạo số nguyên tùy chọn; . Trên các nền tảng có

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
72, đó là bí danh của.

lớp ctypes. c_int8

Đại diện cho kiểu dữ liệu C 8-bit signed int . Thường là một bí danh cho.

lớp ctypes. c_int16

Đại diện cho kiểu dữ liệu C 16-bit signed int . Thường là một bí danh cho.

lớp ctypes. c_int32

Đại diện cho kiểu dữ liệu C 32-bit signed int . Thường là một bí danh cho.

lớp ctypes. c_int64

Đại diện cho kiểu dữ liệu C 64-bit signed int . Thường là một bí danh cho.

lớp ctypes. c_long

Đại diện cho kiểu dữ liệu C signed long . Hàm tạo chấp nhận một trình khởi tạo số nguyên tùy chọn; .

lớp ctypes. c_longlong

Đại diện cho kiểu dữ liệu C signed long long . Hàm tạo chấp nhận một trình khởi tạo số nguyên tùy chọn; .

lớp ctypes. c_short

Đại diện cho kiểu dữ liệu C signed short . Hàm tạo chấp nhận một trình khởi tạo số nguyên tùy chọn; .

lớp ctypes. c_size_t

Đại diện cho kiểu dữ liệu C

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
78

lớp ctypes. c_ssize_t

Đại diện cho kiểu dữ liệu C

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
79

Mới trong phiên bản 3. 2

lớp ctypes. c_ubyte

Đại diện cho kiểu dữ liệu C unsigned char , nó diễn giải giá trị dưới dạng số nguyên nhỏ. Hàm tạo chấp nhận một trình khởi tạo số nguyên tùy chọn; .

lớp ctypes. c_uint

Đại diện cho kiểu dữ liệu C unsigned int . Hàm tạo chấp nhận một trình khởi tạo số nguyên tùy chọn; . Trên các nền tảng có

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
72, nó là bí danh cho.

lớp ctypes. c_uint8

Đại diện cho kiểu dữ liệu C 8-bit unsigned int . Thường là một bí danh cho.

lớp ctypes. c_uint16

Đại diện cho kiểu dữ liệu C 16-bit unsigned int . Thường là một bí danh cho.

lớp ctypes. c_uint32

Đại diện cho kiểu dữ liệu C 32-bit unsigned int . Thường là một bí danh cho.

lớp ctypes. c_uint64

Đại diện cho kiểu dữ liệu C 64-bit unsigned int . Thường là một bí danh cho.

lớp ctypes. c_ulong

Đại diện cho kiểu dữ liệu C unsigned long . Hàm tạo chấp nhận một trình khởi tạo số nguyên tùy chọn; .

lớp ctypes. c_ulonglong

Đại diện cho kiểu dữ liệu C unsigned long long . Hàm tạo chấp nhận một trình khởi tạo số nguyên tùy chọn; .

lớp ctypes. c_ushort

Đại diện cho kiểu dữ liệu C unsigned short . Hàm tạo chấp nhận một trình khởi tạo số nguyên tùy chọn; .

lớp ctypes. c_void_p

Đại diện cho loại C void* . Giá trị được biểu diễn dưới dạng số nguyên. Hàm tạo chấp nhận một trình khởi tạo số nguyên tùy chọn.

lớp ctypes. c_wchar

Đại diện cho kiểu dữ liệu C wchar_t và diễn giải giá trị dưới dạng một chuỗi unicode ký tự đơn. Hàm tạo chấp nhận một trình khởi tạo chuỗi tùy chọn, độ dài của chuỗi phải chính xác là một ký tự.

lớp ctypes. c_wchar_p

Đại diện cho kiểu dữ liệu C wchar_t* , kiểu dữ liệu này phải là một con trỏ tới một chiều rộng kết thúc bằng 0 . Hàm tạo chấp nhận một địa chỉ số nguyên hoặc một chuỗi.

lớp ctypes. c_bool

Đại diện cho kiểu dữ liệu C bool (chính xác hơn là _Bool from C99). Its value can be

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
86 or
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.GetModuleHandleA)  
<_FuncPtr object at 0x...>
>>> print(windll.kernel32.MyOwnFunction)     
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>
21, and the constructor accepts any object that has a truth value.

lớp ctypes. HỆ QUẢ

chỉ cửa sổ. Đại diện cho một giá trị

>>> c_int()
c_long(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140018365411392)
>>> c_ushort(-3)
c_ushort(65533)
>>>
2, chứa thông tin thành công hoặc lỗi cho một lệnh gọi hàm hoặc phương thức

lớp ctypes. py_object

Đại diện cho kiểu dữ liệu C * . Gọi cái này mà không có đối số sẽ tạo ra một con trỏ

>>> cdll.LoadLibrary("libc.so.6")  

>>> libc = CDLL("libc.so.6")       
>>> libc                           

>>>
13 * .

Mô-đun

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
90 cung cấp khá nhiều loại dữ liệu cụ thể khác của Windows, ví dụ như
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
91,
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
92 hoặc
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
93. Một số cấu trúc hữu ích như
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  
<_FuncPtr object at 0x...>
>>>
94 hoặc
/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
90 cũng được định nghĩa

Các kiểu dữ liệu có cấu trúc

lớp ctypes. Liên minh(*args , **kw)

Lớp cơ sở trừu tượng cho các công đoàn theo thứ tự byte gốc

lớp ctypes. BigEndianUnion(*args , **kw)

Lớp cơ sở trừu tượng cho các công đoàn theo thứ tự byte cuối lớn

Mới trong phiên bản 3. 11

lớp ctypes. LittleEndianUnion(*args , **kw)

Lớp cơ sở trừu tượng cho các công đoàn theo thứ tự byte cuối nhỏ

Mới trong phiên bản 3. 11

lớp ctypes. BigEndianStructure(*args , **kw)

Lớp cơ sở trừu tượng cho các cấu trúc theo thứ tự byte cuối lớn

lớp ctypes. LittleEndianStructure(*args , **kw)

Lớp cơ sở trừu tượng cho các cấu trúc theo thứ tự byte cuối nhỏ

Các cấu trúc và liên kết với thứ tự byte không phải gốc không thể chứa các trường loại con trỏ hoặc bất kỳ loại dữ liệu nào khác có chứa các trường loại con trỏ

lớp ctypes. Cấu trúc(*args , **kw)

Lớp cơ sở trừu tượng cho các cấu trúc theo thứ tự byte gốc

Cấu trúc cụ thể và các kiểu kết hợp phải được tạo bằng cách phân lớp một trong các kiểu này và ít nhất là xác định một biến lớp. sẽ tạo s cho phép đọc và ghi các trường bằng cách truy cập thuộc tính trực tiếp. Đây là những

_lĩnh vực_

Trình tự xác định các trường cấu trúc. Các mục phải là 2-bộ hoặc 3-bộ. Mục đầu tiên là tên của trường, mục thứ hai chỉ định loại trường;

Đối với các trường loại số nguyên như , có thể cung cấp mục tùy chọn thứ ba. Nó phải là một số nguyên dương nhỏ xác định độ rộng bit của trường

Tên trường phải là duy nhất trong một cấu trúc hoặc liên kết. Điều này không được kiểm tra, chỉ có thể truy cập một trường khi tên được lặp lại

Có thể định nghĩa biến lớp sau câu lệnh lớp định nghĩa lớp con Cấu trúc, điều này cho phép tạo các kiểu dữ liệu tham chiếu trực tiếp hoặc gián tiếp đến chính chúng

>>> cdll.kernel32.GetModuleHandleA(None)  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>

>>> windll.msvcrt.printf(b"spam")  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>
7

Tuy nhiên, biến lớp phải được định nghĩa trước khi kiểu được sử dụng lần đầu tiên (một thể hiện được tạo, được gọi trên nó, v.v.). Các phép gán sau này cho biến lớp sẽ tăng AttributeError

Có thể định nghĩa các lớp con con của kiểu cấu trúc, chúng kế thừa các trường của lớp cơ sở cộng với các trường được định nghĩa trong lớp con con nếu có

_đóng gói_

Một số nguyên nhỏ tùy chọn cho phép ghi đè căn chỉnh của các trường cấu trúc trong ví dụ. phải được xác định khi được chỉ định, nếu không nó sẽ không có hiệu lực

_vô danh_

Một chuỗi tùy chọn liệt kê tên của các trường chưa được đặt tên (ẩn danh). phải được xác định trước khi được chỉ định, nếu không nó sẽ không có hiệu lực

Các trường được liệt kê trong biến này phải là trường kiểu cấu trúc hoặc liên kết. sẽ tạo các mô tả trong kiểu cấu trúc cho phép truy cập trực tiếp vào các trường lồng nhau mà không cần tạo cấu trúc hoặc trường kết hợp

Đây là một loại ví dụ (Windows)

>>> cdll.kernel32.GetModuleHandleA(None)  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>

>>> windll.msvcrt.printf(b"spam")  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>
8

Cấu trúc

>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
09 mô tả kiểu dữ liệu COM, trường
>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
10 chỉ định một trong các trường liên kết hợp lệ. Vì trường
>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
11 được định nghĩa là trường ẩn danh, nên giờ đây có thể truy cập các thành viên trực tiếp từ phiên bản TYPEDESC.
>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
12 và
>>> cdll.kernel32[1]  
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0]  
Traceback (most recent call last):
  File "", line 1, in 
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>
13 là tương đương, nhưng cái trước nhanh hơn vì nó không cần tạo một thể hiện hợp nhất tạm thời

>>> cdll.kernel32.GetModuleHandleA(None)  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>

>>> windll.msvcrt.printf(b"spam")  
Traceback (most recent call last):
  File "", line 1, in 
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>
9

Có thể định nghĩa các lớp con của cấu trúc, chúng kế thừa các trường của lớp cơ sở. Nếu định nghĩa lớp con có một biến riêng, thì các trường được chỉ định trong phần này sẽ được thêm vào các trường của lớp cơ sở

Các hàm tạo cấu trúc và liên kết chấp nhận cả đối số vị trí và từ khóa. Các đối số vị trí được sử dụng để khởi tạo các trường thành viên theo thứ tự như chúng xuất hiện trong. Các đối số từ khóa trong hàm tạo được hiểu là các thuộc tính được gán, vì vậy chúng sẽ khởi tạo cùng tên hoặc tạo các thuộc tính mới cho các tên không có trong

Mảng và con trỏ

lớp ctypes. Mảng(*args)

Lớp cơ sở trừu tượng cho mảng

Cách khuyến nghị để tạo các kiểu mảng cụ thể là nhân bất kỳ kiểu dữ liệu nào với một số nguyên không âm. Ngoài ra, bạn có thể phân lớp loại này và xác định và các biến lớp. Các phần tử mảng có thể được đọc và ghi bằng cách sử dụng các truy cập lát cắt và chỉ số con tiêu chuẩn;

_chiều dài_

Một số nguyên dương xác định số phần tử trong mảng. Các chỉ số nằm ngoài phạm vi dẫn đến một. Sẽ được trả lại bởi

_loại_

Chỉ định kiểu của từng phần tử trong mảng

Các hàm tạo của lớp con mảng chấp nhận các đối số vị trí, được sử dụng để khởi tạo các phần tử theo thứ tự

lớp ctypes. _Con trỏ

Lớp cơ sở trừu tượng, riêng tư cho con trỏ

Các loại con trỏ cụ thể được tạo bằng cách gọi với loại sẽ được trỏ tới;

Nếu một con trỏ trỏ đến một mảng, các phần tử của nó có thể được đọc và ghi bằng cách sử dụng các truy cập lát cắt và chỉ số con tiêu chuẩn. Các đối tượng con trỏ không có kích thước, vì vậy sẽ tăng. Các chỉ số âm sẽ đọc từ bộ nhớ trước con trỏ (như trong C) và các chỉ số ngoài phạm vi có thể sẽ bị lỗi do vi phạm quyền truy cập (nếu bạn may mắn)

_loại_

Chỉ định loại trỏ đến

nội dung

Trả về đối tượng mà con trỏ trỏ tới. Việc gán cho thuộc tính này sẽ thay đổi con trỏ trỏ đến đối tượng được gán

Python có con trỏ không?

Không, chúng tôi không có bất kỳ loại Con trỏ nào trong ngôn ngữ Python . Các đối tượng được truyền cho hàm theo tham chiếu. Cơ chế được sử dụng trong Python giống hệt như truyền con trỏ theo giá trị trong C. Chúng tôi có các biến Python không phải là con trỏ.

Tại sao con trỏ không có sẵn trong Python?

Con trỏ có xu hướng tạo ra sự phức tạp trong mã, trong đó Python chủ yếu tập trung vào khả năng sử dụng hơn là tốc độ . Kết quả là Python không hỗ trợ con trỏ. Tuy nhiên, Python mang lại một số lợi ích khi sử dụng con trỏ. Trước khi tìm hiểu về con trỏ trong Python, chúng ta cần có khái niệm cơ bản về những điểm sau.

4 loại hàm trong Python là gì?

Sau đây là các loại Hàm Python khác nhau. .
Hàm tích hợp Python
Hàm đệ quy Python
Hàm Lambda trong Python
Các hàm do người dùng định nghĩa trong Python

Chúng ta có thể có một con trỏ tới một hàm không?

Con trỏ tới hàm trỏ tới địa chỉ của mã thực thi của hàm . Bạn có thể sử dụng con trỏ để gọi hàm và truyền hàm làm đối số cho các hàm khác. Bạn không thể thực hiện phép tính số học con trỏ trên con trỏ tới hàm.