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 Show
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 ctypesGhi 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 "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 độngxuấ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 "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) 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")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") Accessing functions from loaded dllsFunctions 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 " Note that win32 system dlls like >>> cdll.LoadLibrary("libc.so.6")01 and >>> cdll.LoadLibrary("libc.so.6")02 often export ANSI as well as UNICODE versions of a function. The UNICODE version is exported with an >>> cdll.LoadLibrary("libc.so.6")03 appended to the name, while the ANSI version is exported with an >>> cdll.LoadLibrary("libc.so.6")04 appended to the name. The win32 >>> cdll.LoadLibrary("libc.so.6")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")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")07 or >>> cdll.LoadLibrary("libc.so.6")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")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 " Calling functionsYou can call these functions like any other Python callable. This example uses the >>> cdll.LoadLibrary("libc.so.6")11 function, which returns system time in seconds since the Unix epoch, and the >>> cdll.LoadLibrary("libc.so.6")12 function, which returns a win32 module handle This example calls both functions with a >>> cdll.LoadLibrary("libc.so.6")13 pointer ( >>> cdll.LoadLibrary("libc.so.6")14 should be used as the >>> cdll.LoadLibrary("libc.so.6")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 "9 calling convention, or vice versa >>> cdll.kernel32.GetModuleHandleA(None) Traceback (most recent call last): File " 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 " 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")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")14 is passed as a C >>> cdll.LoadLibrary("libc.so.6")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")14 wchar_t* (NUL chấm dứt) chuỗi hoặc >>> cdll.LoadLibrary("libc.so.6")14 khoảng trống* int hoặc >>> cdll.LoadLibrary("libc.so.6")14
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")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")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")55; >>> cdll.LoadLibrary("libc.so.6")2 Hàm thay thế hàm >>> cdll.LoadLibrary("libc.so.6")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ụcLư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")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")4 Gọi hàm matrixdicTrê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")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")62 cho tất cả các hàm biến đổi Calling functions with your own custom data typesYou 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")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")6 If you don’t want to store the instance’s data in the >>> cdll.LoadLibrary("libc.so.6")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")62 attribute >>> cdll.LoadLibrary("libc.so.6")62 must be a sequence of C data types (the >>> cdll.LoadLibrary("libc.so.6")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")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")8 If you have defined your own classes which you pass to function calls, you have to implement a >>> cdll.LoadLibrary("libc.so.6")71 class method for them to be able to use them in the >>> cdll.LoadLibrary("libc.so.6")62 sequence. The >>> cdll.LoadLibrary("libc.so.6")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")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")65 attribute Return typesBy default functions are assumed to return the C int type. Other return types can be specified by setting the >>> cdll.LoadLibrary("libc.so.6")77 attribute of the function object. Here is a more advanced example, it uses the >>> cdll.LoadLibrary("libc.so.6")78 function, which expects a string pointer and a char, and returns a pointer to a string >>> cdll.LoadLibrary("libc.so.6")9 If you want to avoid the >>> cdll.LoadLibrary("libc.so.6")79 calls above, you can set the >>> cdll.LoadLibrary("libc.so.6")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 "0 You can also use a callable Python object (a function or a class for example) as the >>> cdll.LoadLibrary("libc.so.6")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 "1 >>> cdll.LoadLibrary("libc.so.6")82 is a function which will call Windows >>> cdll.LoadLibrary("libc.so.6")83 api to get the string representation of an error code, and returns an exception. >>> cdll.LoadLibrary("libc.so.6")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")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 "2 Structures and unionsStructures 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")95 attribute. >>> cdll.LoadLibrary("libc.so.6")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 "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 "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 "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 "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 orderBy 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 "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 "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 unionsIt 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")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 "7 ArraysArrays 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 "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 "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 "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 PointersPointer 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 "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")13 pointer. >>> cdll.LoadLibrary("libc.so.6")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 "21 boolean value /* ANSI version */ HMODULE GetModuleHandleA(LPCSTR lpModuleName); /* UNICODE version */ HMODULE GetModuleHandleW(LPCWSTR lpModuleName);9 checks for >>> cdll.LoadLibrary("libc.so.6")13 when dereferencing pointers (but dereferencing invalid non- >>> cdll.LoadLibrary("libc.so.6")13 pointers would crash Python) >>> getattr(cdll.msvcrt, "??2@YAPAXI@Z") <_FuncPtr object at 0x...> >>>0 Type conversionsUsually, 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 "25 in the >>> cdll.LoadLibrary("libc.so.6")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 "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 "25) in >>> cdll.LoadLibrary("libc.so.6")62, an object of the pointed type ( >>> windll.kernel32.GetModuleHandleA(32) Traceback (most recent call last): File "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")13, you can assign >>> cdll.LoadLibrary("libc.so.6")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 "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 "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 "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 "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 "36 the structure >>> getattr(cdll.msvcrt, "??2@YAPAXI@Z") <_FuncPtr object at 0x...> >>>5 Incomplete TypesIncomplete 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 "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 "48 class and set the >>> cdll.LoadLibrary("libc.so.6")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 "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 functionsallows 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 "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 "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 "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 "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 "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 "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 "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 "2 Kết quả >>> cdll.kernel32[1] <_FuncPtr object at 0x...> >>> cdll.kernel32[0] Traceback (most recent call last): File "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 "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 "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 "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ừ dllSome 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 "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 "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 "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 "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ị đó
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 "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 "9 Vì >>> 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 "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 "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")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 "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 "82 chẳng hạn ngạc nhiênThere 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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 đổicung 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 ctypesTìm thư viện dùng chungKhi 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ảictypes. 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")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")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 chungCó 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_GLOBALGắ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_LOCALGắ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_MODEChế độ 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ênThe 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")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ảilớ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ầnLoadLibrary(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. cdllTạo phiên bản ctypes. gióchỉ cửa sổ. Tạo phiên bản ctypes. oledllchỉ cửa sổ. Tạo phiên bản ctypes. pydllTạ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. pythonapiMộ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")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àiNhư đã 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. _FuncPtrBase 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 restypeAssign a ctypes type to specify the result type of the foreign function. Use >>> cdll.LoadLibrary("libc.so.6")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. argtypesAssign 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")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")71 method which returns a value usable as argument (integer, string, ctypes instance). This allows defining adapters that can adapt custom objects as function parameterserrcheck 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")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. ArgumentErrorThis 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 prototypesForeign 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 abovectypes. 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
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 "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 "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 "2 Here is the wrapping with >>> cdll.kernel32.GetModuleHandleA(None) Traceback (most recent call last): File "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")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 "4 Nếu hàm >>> cdll.LoadLibrary("libc.so.6")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 "5 Các chức năng tiện íchctypes. đị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);99ctypes. 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 "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ềuctypes. 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 "81ctypes. 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 "81ctypes. 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ấtctypes. 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")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")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([mã]) 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")85, nó không trả về bản sao mã lỗi ctypes-privatectypes. 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ềuctypes. 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ộ đệmctypes. 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);31ctypes. 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...> >>>31ctypes. 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...> >>>32ctypes. 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 "81ctypes. WinError(mã=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 "81 Loại dữ liệulớp ctypes. _CDataLớ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 "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 "81, >>> getattr(cdll.msvcrt, "??2@YAPAXI@Z") <_FuncPtr object at 0x...> >>>48from_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 "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 "81, >>> getattr(cdll.msvcrt, "??2@YAPAXI@Z") <_FuncPtr object at 0x...> >>>48from_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...> >>>34from_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")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ượngThành viên này là >>> cdll.LoadLibrary("libc.so.6")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ảnlớp ctypes. _SimpleCDataLớ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")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")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")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")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...> >>>78lớ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 "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ứclớ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")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úclớ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 "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 "8 Cấu trúc >>> cdll.kernel32[1] <_FuncPtr object at 0x...> >>> cdll.kernel32[0] Traceback (most recent call last): File "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 "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 "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 "12 và >>> cdll.kernel32[1] <_FuncPtr object at 0x...> >>> cdll.kernel32[0] Traceback (most recent call last): File "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 "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 dungTrả 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. |