广告位联系
返回顶部
分享到

python中ctypes使用方法介绍

python 来源:互联网 作者:佚名 发布时间:2024-04-24 22:11:38 人浏览
摘要

前段时间接到了一个需求是给一个蓝牙的SDK测试接口的稳定性,将SDK的接口文档给你了,需要每个接口都写一个对应的测试用例,SDK 是用c写的,而我python用的比较熟练些,所有记录下在ctype

前段时间接到了一个需求是给一个蓝牙的SDK测试接口的稳定性,将SDK的接口文档给你了,需要每个接口都写一个对应的测试用例,SDK 是用c写的,而我python用的比较熟练些,所有记录下在ctypes库的使用方法。

1 python和c中类型映射

ctypes中数据类型

ctypes 类型 C 类型 Python 数据类型
c_bool _Bool bool (1)
c_char char 单字符字节串对象
c_wchar wchar_t 单字符字符串
c_byte char int
c_ubyte unsigned char int
POINTER(c_ubyte) uchar* int
c_short short int
c_ushort unsigned short int
c_int int int
c_uint unsigned int int
c_long long int
c_ulong unsigned long int
c_longlong __int64 或 long long int
c_ulonglong unsigned __int64 或 unsigned long long int
c_size_t size_t int
c_ssize_t ssize_t 或 Py_ssize_t int
c_float float float
c_double double float
c_longdouble long double float
c_char_p char * (NUL terminated) 字节串对象或 None
c_wchar_p wchar_t * (NUL terminated) 字符串或 None
c_void_p void * int 或 None

2 加载共享库

1

2

3

4

import ctypes 

# 加载本地的共享库,路径根据实际情况调整 

lib = ctypes.CDLL('./libexample.so')  # Linux/macOS平台 

# lib = ctypes.WinDLL('example.dll')  # Windows平台

3 调用函数

1

2

3

4

5

6

7

# 设置参数类型 

lib.add.argtypes = [ctypes.c_int, ctypes.c_int] 

# 设置返回类型 

lib.add.restype = ctypes.c_int 

# 调用C函数 

result = lib.add(2, 3) 

print(result)  # 输出:5

4 操作指针

在ctypes中,你可以使用pointer和byref来操作指针。

1

2

3

4

5

6

7

8

9

10

11

12

# 创建一个整数数组 

arr = (ctypes.c_int * 5)(1, 2, 3, 4, 5) 

# 获取指向数组首元素的指针 

ptr = ctypes.pointer(arr) 

# 通过指针访问数组元素 

print(ptr[0])  # 输出:1 

# 使用byref创建指向变量的指针 

x = ctypes.c_int(10) 

px = ctypes.byref(x) 

# 通过指针修改变量的值 

lib.increment(px)  # 假设有一个increment函数用于增加整数的值 

print(x.value)  # 输出:11

1

2

3

4

5

6

7

8

9

10

# 调用系统的库函数测试

from ctypes import c_int, c_float, create_string_buffer, CDLL, byref

c_lib = CDLL('/lib/x86_64-linux-gnu/libc.so.6')

i = c_int()

f = c_float()

s = create_string_buffer(b"\000" * 32)

print(i.value, f.value, repr(s.value))

# brref 传入数据类型返回指针的地址, create_string_buffer返回的是指针

c_lib.sscanf(b"1 3.14 Hello", b"%d %f %s", byref(i), byref(f), s)

print(i.value, f.value, repr(s.value))

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

from ctypes import c_int, POINTER, cdll

i = c_int(42)   # 创建一个int类型变量

pi = POINTER(c_int)(i)  # 定义一个指向int类型的指针

print(pi.contents)   # 打印指针指向的内存地址

print(pi.contents.value)   # 打印指针指向的值

# 定义C库中的函数原型

sum_func = cdll.LoadLibrary('./test1.so').sums

sum_func.argtypes = [POINTER(c_int), POINTER(c_int)]    # 定义函数参数类型为指针类型

sum_func.restype = POINTER(c_int)   # 定义函数返回值类型为指针类型

pointer = POINTER(c_int)

# 调用sum()函数

a = c_int(1)

b = c_int(2)

c = sum_func(pointer(a), pointer(b))   # 将a、b的地址传递给sum()函数

print(c.contents.value)   # 打印返回值

5 操作结构体和联合体

你需要定义结构体或联合体的类型,然后可以创建实例、访问其成员等。

1

2

3

4

5

6

7

8

9

# 定义C语言的结构体类型 

class Point(ctypes.Structure): 

    _fields_ = [("x", ctypes.c_int), ("y", ctypes.c_int)] 

# 创建结构体的实例 

p = Point() 

p.x = 10 

p.y = 20 

# 将结构体的实例传递给C函数 

lib.print_point(p)  # 假设有一个print_point函数用于打印点的坐标

6 处理字符串

字符串通常以字符数组或字符指针的形式存在。在ctypes中,你可以使用create_string_buffer来创建C风格的字符串,或者使用c_char_p来操作字符串指针。

1

2

3

4

5

6

7

8

# 创建C风格的字符串 

c_str = ctypes.create_string_buffer(b"Hello, World!") 

# 将字符串传递给C函数 

lib.print_string(c_str)  # 假设有一个print_string函数用于打印字符串 

# 处理C语言中的字符串指针 

c_char_p_type = ctypes.POINTER(ctypes.c_char) 

c_char_p = c_char_p_type.from_buffer(c_str) 

lib.print_string_ptr(c_char_p)  # 假设有一个print_string_ptr函数接收字符串指针

7 回调函数

c 中很多实现异步的方式通过回调函数事件触发的方式,ctype中也能将ctype定义的函数传入c中执行

1

2

3

4

5

6

7

8

9

10

# include "stdio.h"

typedef int (*CallbackFunc)(int, int);

int c_sub(int x, int y){

    printf("c callback func\n");

    return x - y;

}

void call_callback(CallbackFunc callback){

    int result = callback(3, 4);

    printf("result from c: %d\n", result);

}

1

2

3

4

5

6

7

8

9

10

11

12

import ctypes

my_lib = ctypes.CDLL("./test2.so")

callback_type = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int)

def python_sub(a, b):

    print("python callback func")

    return b - a

# 1.调用c中的函数,回调函数从python中传入

python_callback = callback_type(python_sub)

my_lib.call_callback(python_callback)

# 2.调用c中的函数,回调从c中传入

c_callback = callback_type(my_lib.c_sub)

my_lib.call_callback(c_callback)


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计