使用ctypes实现python类型和C语言类型之间的相互转化

楔子

我们知道可以使用ctypes调用扩展模块,主要是调用扩展模块中使用C编写好的函数,但这些函数肯定都是需要参数的,还有返回值,不然编写扩展模块有啥用呢。那么问题来了,不同的语言变量类型不同,所以python能够直接往C编写的函数中传参吗?显然不行,所以ctypes还提供了大量的类,帮我们将python中的类型转成C语言中的类型。

python类型与C语言类型之间的转换

我们说了,python中类型不能直接往C语言的函数中传递(整型是个例外),那么ctypes就提供了很多的类可以帮助我们将python的类型转成C语言的类型。常见的类型分为以下几种:数值、字符、指针

数值类型转换

c语言的数值类型分为如下:

  • int:整型
  • unsigned int:无符号整型
  • short:短整型
  • unsigned short:无符号短整型
  • long:长整形
  • unsigned long:无符号长整形
  • long long:64位机器上等同于long
  • unsigned long long:等同于unsigned long
  • float:单精度浮点型
  • double:双精度浮点型
  • long double:看成是double即可
  • _Bool:布尔类型
  • ssize_t:等同于long或者long long
  • size_t:等同于unsigned long或者unsigned long long

import ctypes

# 下面都是ctypes中提供的类,将python中的对象传进去,就可以转换为C语言能够识别的类型
print(ctypes.c_int(1))  # c_long(1)
print(ctypes.c_uint(1))  # c_ulong(1)
print(ctypes.c_short(1))  # c_short(1)
print(ctypes.c_ushort(1))  # c_ushort(1)
print(ctypes.c_long(1))  # c_long(1)
print(ctypes.c_ulong(1))  # c_ulong(1)

# c_longlong等价于c_long,c_ulonglong等价于c_ulong
print(ctypes.c_longlong(1))  # c_longlong(1)
print(ctypes.c_ulonglong(1))  # c_ulonglong(1)

print(ctypes.c_float(1.1))  # c_float(1.100000023841858)
print(ctypes.c_double(1.1))  # c_double(1.1)

# 在64位机器上,c_longdouble等于c_double
print(ctypes.c_longdouble(1.1))  # c_double(1.1)

print(ctypes.c_bool(True))  # c_bool(True)

# 相当于c_longlong和c_ulonglong
print(ctypes.c_ssize_t(10))  # c_longlong(10)
print(ctypes.c_size_t(10))  # c_ulonglong(10)

字符类型转换

c语言的字符类型分为如下:

  • char:一个ascii字符或者-128~127的整型
  • wchar:一个unicode字符
  • unsigned char:一个ascii字符或者0~255的一个整型

import ctypes

# 必须传递一个ascii字符并且是字节,或者一个int,来代表c里面的字符
print(ctypes.c_char(b"a"))  # c_char(b'a')
print(ctypes.c_char(97))  # c_char(b'a')

# 传递一个unicode字符,当然ascii字符也是可以的,并且不是字节形式
print(ctypes.c_wchar("憨"))  # c_wchar('憨')

# 和c_char类似,但是c_char既可以传入字符、也可以传整型,而这里的c_byte则要求必须传递整型。
print(ctypes.c_byte(97))  # c_byte(97)
print(ctypes.c_ubyte(97))  # c_ubyte(97)

指针类型转换

c语言的指针类型分为如下:

  • char *:字符指针
  • wchar_t *:字符指针
  • void *:空指针

import ctypes

# c_char_p就是c里面字符数组指针了
# char *s = "hello world";
# 那么这里面也要传递一个bytes类型的字符串,返回一个地址
print(ctypes.c_char_p(b"hello world"))  # c_char_p(2082736374464)

# 直接传递一个unicode,同样返回一个地址
print(ctypes.c_wchar_p("憨八嘎~"))  # c_wchar_p(2884583039392)

# ctypes.c_void_p后面演示

至于其他的类型,比如整型指针啊、数组啊、结构体啊、回调函数啊,ctypes都支持,我们后面会介绍。

猜你喜欢

转载自www.cnblogs.com/traditional/p/12238329.html