链接:
作用:
- ctypes允许在没有创建封装函数的前提下调用动态库中的函数,函数调用采用纯python方式
Example:
- C++代码:
- #include <iostream>
- class TestFact{
- public:
- TestFact(){};
- ~TestFact(){};
- int fact(int n);
- }
- int TestFact::fact(int n){
- if(n < 1) return n;
- else return n*(n-1);
- }
- extern "C" int fact(int n){
- TestFact t;
- return t.fact(n);
- }
- 编译命令:g++ -o test.so -shared -fPIC test.cpp
- Python代码:
- import ctypes
- lib = ctypes.cdll.LoadLibrary("test.so") #lib = ctypes.CDLL("test.so")
- print lib.fact(3)
调用系统函数:
- import ctypes
- libc = ctypes.CDLL('libc.so.6')
- libc.printf("%d", 2)
- print libc.time(None)
- print libc.atoi("234")
类型转换:
- import ctypes
- >>> b = ctypes.c_bool(1)
- >>> print b
- c_bool(True)
- >>> b = ctypes.c_bool(0)
- >>> print b
- c_bool(False)
- >>> print b.value
- False
- >>> from ctypes import *
- >>> p = create_string_buffer(3)
- >>> print sizeof(p), repr(p)
- 3 <ctypes.c_char_Array_3 object at 0x02DEF080>
- >>> print sizeof(p), repr(p.raw)
- 3 '\x00\x00\x00'
- >>> p = create_string_buffer('hello')
- >>> print sizeof(b), repr(p.raw)
- 1 'hello\x00'
- >>> print sizeof(p), repr(p.raw)
- 6 'hello\x00'
- >>> p = create_string_buffer('hello', 10)
- >>> print sizeof(p), repr(p.raw), repr(p.value)
- 10 'hello\x00\x00\x00\x00\x00' 'hello'
函数返回类型:
- >>> from ctypes import *
- >>> libc = CDLL('libc.so.6')
- >>> libc.strchr('abcdef', ord('d'))
- -370912089
- >>> ord('d')
- 100
- >>> libc.strchr('abcdef', 'd')
- 0
- >>> strchr = libc.strchr
- >>> strchr.restype = c_char_p #函数默认返回C int类型,如果需要返回其它类型,需要设置函数的restype属性
- >>> strchr("abcdef", ord("d"))
- 'def'
传递指针或者引用:
- 很多情况下 C 函数需要传递指针或者引用,ctypes也完美的支持这一点:byref() 用来传递引用参数,pointer() 函数也可以完成同样的工作,但pointer()会创建一个实际的指针对象,如果你不需要一个指针对象,用byref()会快很多
- >>> i = c_int()
- >>> f = c_float()
- >>> s = create_string_buffer('/000'*32)
- >>> print i.value, f.value, repr(s.value)
- 0 0.0 '/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000/000'
- >>> libc.sscanf("1 3.14 hello", "%d %f %s",byref(i), byref(f), s)
- 3
- >>> print i.value, f.value, repr(s.value)
- 1 3.1400001049 'hello'
- 通过pointer()函数创建指针
- >>> i = c_int(42)
- >>> pi = pointer(i) #创建指针
- >>> pi.contents
- c_int(42)
- >>> pi.contents = c_int(99) #给指针赋值
- >>> pi.contents
- c_int(99)
- >>> pi[0] #通过数组方式访问指针的内容
- 99
- >>> pi[0] = 100 #通过数组方式修改指针的内容
- >>> pi[0]
- 100
- >>>
ctypes数据类型与C数据类型对照表:
ctypes type | C type | Python type |
---|---|---|
c_bool | _Bool | bool (1) |
c_char | char | 1-character string |
c_wchar | wchar_t | 1-character unicode string |
c_byte | char | int/long |
c_ubyte | unsigned char | int/long |
c_short | short | int/long |
c_ushort | unsigned short | int/long |
c_int | int | int/long |
c_uint | unsigned int | int/long |
c_long | long | int/long |
c_ulong | unsigned long | int/long |
c_longlong | __int64 or long long | int/long |
c_ulonglong | unsigned __int64 or unsigned long long | int/long |
c_float | float | float |
c_double | double | float |
c_longdouble | long double | float |
c_char_p | char * (NUL terminated) | string or None |
c_wchar_p | wchar_t * (NUL terminated) | unicode or None |
c_void_p | void * | int/long or None |