Python--ctypes

链接
作用
  • ctypes允许在没有创建封装函数的前提下调用动态库中的函数,函数调用采用纯python方式
Example
  • C++代码:
  1. #include <iostream>
  2. class TestFact{
  3.     public:
  4.         TestFact(){};
  5.         ~TestFact(){};
  6.         int fact(int n);
  7. }
  8. int TestFact::fact(int n){
  9.     if(n < 1) return n;
  10.     else return n*(n-1);
  11. }
  12. extern "C" int fact(int n){
  13.     TestFact t;
  14.     return t.fact(n);
  15. }
  16. 编译命令:g++ -o test.so -shared -fPIC test.cpp
  • Python代码:
  1. import ctypes
  2. lib = ctypes.cdll.LoadLibrary("test.so") #lib = ctypes.CDLL("test.so")
  3. print lib.fact(3)
调用系统函数:
  1. import ctypes
  2. libc = ctypes.CDLL('libc.so.6')
  3. libc.printf("%d", 2)
  4. print libc.time(None)
  5. print libc.atoi("234")
类型转换:
  1. import ctypes
  2. >>> b = ctypes.c_bool(1)
  3. >>> print b
  4. c_bool(True)
  5. >>> b = ctypes.c_bool(0)
  6. >>> print b
  7. c_bool(False)
  8. >>> print b.value
  9. False
  10. >>> from ctypes import *
  11. >>> p = create_string_buffer(3)
  12. >>> print sizeof(p), repr(p)
  13. 3 <ctypes.c_char_Array_3 object at 0x02DEF080>
  14. >>> print sizeof(p), repr(p.raw)
  15. 3 '\x00\x00\x00'
  16. >>> p = create_string_buffer('hello')
  17. >>> print sizeof(b), repr(p.raw)
  18. 1 'hello\x00'
  19. >>> print sizeof(p), repr(p.raw)
  20. 6 'hello\x00'
  21. >>> p = create_string_buffer('hello', 10)
  22. >>> print sizeof(p), repr(p.raw), repr(p.value)
  23. 10 'hello\x00\x00\x00\x00\x00' 'hello'
函数返回类型:
  1. >>> from ctypes import *
  2. >>> libc = CDLL('libc.so.6')
  3. >>> libc.strchr('abcdef', ord('d'))
  4. -370912089
  5. >>> ord('d')
  6. 100
  7. >>> libc.strchr('abcdef', 'd')
  8. 0
  9. >>> strchr = libc.strchr
  10. >>> strchr.restype = c_char_p #函数默认返回C int类型,如果需要返回其它类型,需要设置函数的restype属性
  11. >>> strchr("abcdef", ord("d"))
  12. 'def'
传递指针或者引用:
  • 很多情况下 C 函数需要传递指针或者引用,ctypes也完美的支持这一点:byref() 用来传递引用参数,pointer() 函数也可以完成同样的工作,但pointer()会创建一个实际的指针对象,如果你不需要一个指针对象,用byref()会快很多
  1. >>> i = c_int()
  2. >>> f = c_float()
  3. >>> s = create_string_buffer('/000'*32)
  4. >>> print i.value, f.value, repr(s.value)
  5. 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'
  6. >>> libc.sscanf("1 3.14 hello", "%d %f %s",byref(i), byref(f), s)
  7. 3
  8. >>> print i.value, f.value, repr(s.value)
  9. 1 3.1400001049 'hello'
  • 通过pointer()函数创建指针
  1. >>> i = c_int(42)
  2. >>> pi = pointer(i) #创建指针
  3. >>> pi.contents
  4. c_int(42)
  5. >>> pi.contents = c_int(99) #给指针赋值
  6. >>> pi.contents
  7. c_int(99)
  8. >>> pi[0] #通过数组方式访问指针的内容
  9. 99
  10. >>> pi[0] = 100 #通过数组方式修改指针的内容
  11. >>> pi[0]
  12. 100
  13. >>> 
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值