ctype说明
ctypes是Python的一个外部库,可以通过Ctypes调用C/C++语言的函数。
ctypes与C语言类型
ctypes type | c type | python type |
---|---|---|
c_bool | _Bool | bool(1) |
c_char | char | 1-character bytes objecg |
c_wchar | wchar_t | 1-character string |
c_ubyte | unsigned char | int |
c_short | short | int |
c_ushort | unsigned short | int |
c_int | int | int |
c_long | long | int |
c_ulong | unsigned long | int |
c_longlong | __int64 or long long | int |
c_ulonglong | unsigned __int64 or unsigned long long | int |
c_size_t | size_t | int |
c_ssize_t | ssize_t or py_ssize_t | int |
c_float | float | float |
c_double | double | float |
c_longdouble | long double | float |
c_char_p | char *(NUL terminated) | byte object or None |
c_wchar_p | wchar_t *(Nul terminated) | string or None |
c_void_p | void * | int or None |
传递数字类型
C语言代码
extern "C" LIB void testNumber(int number, float score, bool isFlag)
{
printf("%d %f %d ", number, score, isFlag);
if (isFlag)
{
printf("isFlag true");
}
else
{
printf("isFlag false");
}
}
python代码
# 引入ctypes模块
from ctypes import *
# 加入dll 动态库
lib= CDLL("test")
try:
lib.testNumber(c_int(101), c_float(88.1), True)
except Exception as ex:
print("testNumber error",ex)
pass
#等于用户输入,程序不退出
input()
传递普通字符类型
C语言代码
LIB void testStr(const char *str,int size)
{
printf("testStr :%s %d", str, size);
}
python代码
# 引入ctypes模块
from ctypes import *
# 加入dll 动态库
lib= CDLL("test")
try:
#将字符串转换 bin
str1=b"hello world"
lib.testStr(str1, c_int(len(str1)))
except Exception as ex:
print("testStr error",ex)
pass
#等于用户输入,程序不退出
input()
传递宽字符类型
C语言代码
LIB void testWStr(const wchar_t *str, int size)
{
printf("testWStr :%ls %d", str, size);
}
python代码
# 引入ctypes模块
from ctypes import *
# 加入dll 动态库
lib= CDLL("test")
try:
#将字符串转换 bin
wstr1="hello world"
lib.testWStr(wstr1, c_int(len(wstr1)))
except Exception as ex:
print("testStr error",ex)
pass
#等于用户输入,程序不退出
input()
传递可修改字符串
C语言代码
LIB void testStrBuff(char *str,int size)
{
str[0] = 'a';
str[1] = 'b';
str[2] = '\0';//字符串结尾
printf("testStrBuff :%s %d", str, size);
}
python代码
# 引入ctypes模块
from ctypes import *
# 加入dll 动态库
lib= CDLL("test")
try:
#可修改字符串
buf=create_string_buffer(100)
lib.testStrBuff(buf,c_int(len(buf)))
print("in python buffer = ",buf.raw,buf.value,len(buf),sep="\n")
except Exception as ex:
print("testStr error",ex)
pass
#等于用户输入,程序不退出
input()
传递数组
C语言代码
//传递数组类型
LIB void testArray(int *arr,int size)
{
for(int i=0;i<size;i++)
{
printf("%d\n", arr[i]);
}
}
python代码
from ctypes import *
lib=CDLL("test")
# 传递数组
arr=[1,2,3,4,5,6]
# 转换数组类型
arrType=c_int*len(arr)
# *将list中每一个元素当做位置参数,等同于 tenArrType(1,2,3,...)
carr=arrType(*arr)
# (arrType,) 中的逗号是让python解析是一个元组
lib.testArray.argtypes=(arrType,)
lib.testArray(carr,len(arr))
返回值函数
C语言代码
//返回整型
LIB int returnInt()
{
return 100;
}
//返回普通字符串
LIB char * returnStr()
{
static char str[] = "returnStr";
return str;
}
//返回宽字符
LIB wchar_t * returnWStr()
{
static wchar_t str[] = L"returnWStr";
return str;
}
python代码
lib=CDLL("test")
# 返回整型
re=lib.returnInt();
print("returnInt=",re)
#返回 普通字符串
lib.returnStr.restype=c_char_p
re=lib.returnStr()
print("returnStr=",re)
#返回宽字符
lib.returnWStr.restype=c_wchar_p
re=lib.returnWStr()
print("returnWStr=",re)
传递指针和返回指针
C语言代码
//传递指针并且返回指针
LIB int* testPointer(float *fp)
{
//修改传递的指针
*fp = 78.6f;
static int re = 1001;
//返回指针
return &re;
}
python代码
from ctypes import *
lib=CDLL("test")
# 形参类型 要传递元组 POINTER返回指针类型
# (POINTER(c_float),) 中逗号是用来表示元组,切记一定加上
lib.testPointer.argtypes=(POINTER(c_float),)
#返回值类型
lib.testPointer.restype=POINTER(c_int)
#定义参数
testf1=c_float(8.5)
# byref(testf1) 将指针传递进去
re=lib.testPointer(byref(testf1))
#打印修改后的指针
print("input testf1=",testf1)
#获取指针的值 .contents.value
print("return=",re.contents.value)
print("return=",type(re))
回调函数
C语言代码
//定义回调函数
typedef void(*Callback)(int a);
//
LIB void testCallback(int *arr,int size,Callback call)
{
for (int i = 0; i < size; i++)
{
printf("%d \n", arr[i]);
}
//调用回调函数
call(200);
}
python代码
from ctypes import *
lib=CDLL("test")
# 回调函数类型
# CFUNCTYPE(返回值,传递类型....)
FUNT=CFUNCTYPE(None,c_int)
#声明回调函数
def callback(a):
print(a,end="\n")
pass
#设置数组
arr=[1,2,3,4]
ArrType=c_int*len(arr)
carr=ArrType(*arr)
# 设置入参类型
lib.testCallback.argtypes=(ArrType,c_int,FUNT)
# 调用c语言函数
lib.testCallback(carr,c_int(len(arr)),FUNT(callback))
传递结构体
C语言代码
/*
pos1 普通结构体
pos2 指针结构体
posArr3 数组结构体
*/
LIB Position * testStruct(Position pos1, Position* pos2, Position* posArr3, int size)
{
printf("pos1=%d,%d \n", pos1.x, pos1.y);
printf("pos2=%d,%d \n", pos2->x, pos2->y);
for (int i = 0; i < size; i++)
{
printf("posArr3=[%d,%d] \t", posArr3[i].x, posArr3[i].y);
}
//返回指针,这里加的static是因为 p1是局部变量,返回后c语言自动清除掉对象。static设置全局变量
static struct Position p1;
p1.x = 43;
p1.y = 200;
return &p1;
}
python代码
from ctypes import *
# 定义结构体
class Position(Structure):
_fields_=[("x",c_int),("y",c_int)]
pass
lib=CDLL("test")
# 传递普通结构体
pos1=Position(11,22)
# 传递指针结构体
pos2=Position(2,2)
# 传递数组结构体
pos3Arra=[Position(2,3),Position(4,3)]
arrType=Position*len(pos3Arra)
carr=arrType(*pos3Arra)
# 设置入参类型,1 普通结构体 2指针结构体 3 数组结构体 4数组长度
lib.testStruct.argtypes=(Position,POINTER(Position),arrType,c_int)
# 设置返回类型
lib.testStruct.restype=POINTER(Position)
re=lib.testStruct(pos1,byref(pos2),carr,len(pos3Arra))
# 获取返回值
print("\n")
print(re.contents.x,re.contents.y,sep="\t")
跨平台调用C语言动态库
from ctypes import *
from platform import system
sys=system()
if sys == "Windows":
lib = CDLL("test")
elif sys == "Linux":
lib = CDLL("test.so")
elif sys == "Darwin": # macos
lib = CDLL("test.lib")
else:
print(" unkon system ")
lib.print(b"hello world")
调用win32函数
from ctypes import *
#API函数 参考https://blog.csdn.net/wang13342322203/article/details/81280377
# 调用win32 提示框
re=windll.user32.MessageBoxA(0,"我是一个窗口".encode("gbk"),"系统提示".encode("gbk"),1) #0普通窗口 ,1确认窗口
if(re==1):
windll.user32.MessageBoxW(0,"点击了确认按钮","系统提示",0)
else:
windll.user32.MessageBoxW(0,"点击了取消按钮","系统提示",0)
网友评论