美文网首页
Python调用C语言函数

Python调用C语言函数

作者: 何亮hook_8285 | 来源:发表于2021-09-20 02:22 被阅读0次

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)

相关文章

  • Python调用C语言函数

    ctype说明 ctypes是Python的一个外部库,可以通过Ctypes调用C/C++语言的函数。 ctype...

  • 使用ctypes模块在Python代码调用C函数

    使用Python语言进行编程的时候可能会需要调用用C语言开发的库,那么如何调用呢,传递给C函数的参数以及返回值如何...

  • C++ 调用Python3

    作为一种胶水语言,Python 能够很容易地调用 C 、 C++ 等语言,也能够通过其他语言调用 Python 的...

  • [转载]C语言函数调用栈

    原文地址:C语言函数调用栈(一)C语言函数调用栈(二) 0 引言 程序的执行过程可看作连续的函数调用。当一个函数执...

  • Runtime之消息发送

    调用对象的方法,在Objective-C中叫做传递消息,先来看一下C语言中的函数调用方式 C语言中的函数调用方式 ...

  • 是否还需要在源文件中添加“extern C”?

    c++调用c语言的函数时我们一般在c语言函数声明处用extern "C"包c函数。例如: extern "C"的主...

  • cgo

    cgo cgo是用来在Go语言中调用C语言的工具 Go语言调用C语言 简单C语言函数 在Go语言中需要通过impo...

  • iOS 理解Block的调用

    Block是C语言的扩充功能。 1.先看看C语言的函数: 直接调用: 使用函数指针调用: 将func赋值给func...

  • gcc

    C语言 c语言是面向函数的语言,所以c语言中全部都是函数 看看单文件中对函数的生命和调用。 要先对函数进行声明再进...

  • 2018-08-29日常C笔记

    C语言初学笔记 C语言程序是由函数组成的C语言程序启动时,系统就会自动调用名字叫main的函数C语言规定了函数定义...

网友评论

      本文标题:Python调用C语言函数

      本文链接:https://www.haomeiwen.com/subject/wakmgltx.html