ctypes python与c c++交互

简介

ctypes是一个自Python 2.5开始引入的,Python自带的函数库。其提供了一系列与C、C++语言兼容的数据结构类与方法,可基于由C源代码编译而来的DLL动态链接库文件,进行Python程序与C程序之间的数据交换与相互调用。

注意:Python解释器与C编译器所支持的位数必须一致

加载动态链接库取出函数

from ctypes import *   
mydll = cdll.LoadLibrary(dllpath)   #dllpath是字符串
mydll = windll.LoadLibrary(dllpath)

上面两行使用哪一行,取决于导出函数的调用规范(cdecl或stdcall).也可以使用下面两行代替:

mydll = CDLL(dllpath)    #注意和上面大小写的区别
mydll = WinDLL(dllpath) 

注:windows下是dll,Linux下是so

导出函数

func = mydll.func_name  #func_name 是dll的导出函数
func.argtypes = (c_int, c_int,c_int,c_void_p) #设置函数参数类型为 int,int,int,void *
func.restype  = c_float #设置返回值类型为 float

ctypes 数据类型

ctypes类型C 类型Python 类型
c_charchar1-character string
c_wcharwchar_t1-character unicode string
c_bytecharint/long
c_ubyteunsigned charint/long
c_boolboolbool
c_shortshortint/long
c_ushortunsigned shortint/long
c_intintint/long
c_uintunsigned intint/long
c_longlongint/long
c_ulongunsigned longint/long
c_longlong__int64 or longlongint/long
c_ulonglongunsigned __int64 or unsigned long longint/long
c_floatfloatfloat
c_doubledoublefloat
c_longdoublelong double floatfloat
c_char_pchar *string or None
c_wchar_pwchar_t *unicode or None
c_void_pvoid *int/long or None

结构体

自定义的结构体和联合体必须继承自ctypes的Structure和Union,这两个类都在ctypes模块中定义。每一个子类必须定义"_fields_"属性,"_fields_"是一个二维的tuples列表,

例如有一个简单结构,包含两个整型x和y,可如下初始化一个结构:

from ctypes import *  
import types  
    
class Point(Structure):  
    _fields_ = [('x', c_int),  
                ('y', c_int)]  
p1 = Point(1,2)  
print(point.x, point.y) #输出 1 2

数组

from ctypes import *

class POINT(Structure):
    _fields_ = [("x", c_int), ("y", c_int)]

TenPointsArrayType=POINT*10   #创建一个数组类型,它是10个Point元素组成的数组。

class MyStruct(Structure):
    _fields_ = [("a", c_int),
                ("b", c_float),
                ("pts", POINT*4)] # 相当于C语言的:  POINT pts[4]

print(len(MyStruct().point_array)) #输出  4

arr = TenPointsArrayType()  #创建一个数组类的对象。
for pt in arr:
    print(pt.x, pt.y)

TenIntegers = c_int*10  # 定义一个int[10]的类型(类)

ii = TenIntegers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) #显式初始化数组(类)
for i in ii: 
  print(i)

指针

type_p_int = POINTER(c_int)  #创建指针类型,它指向整数
v = c_int(4)                 #定义一个整数,值为4.
p_int = type_p_int(v)        #给一个指针变量(p_int)赋值(为变量v的地址).

print(p_int[0])
print(p_int.contents) #指针实例有一个contents属性,返回这个指针所指向的对象。

上面这段代码在C语言里相当于:

typedef int * type_p_int;
int v = 4;
type_p_int p = &v;
printf("%d",p[0]);
printf("%d",*p);

实例

c

#include   
#include   
#include   
  
typedef struct StructPointerTest  
{  
    char name[20];  
    int age;  
}StructPointerTest, *StructPointer;  
  
StructPointer testfunction()    // 返回结构体指针  
{   
    StructPointer p = (StructPointer)malloc(sizeof(StructPointerTest));   
    strcpy(p->name, "Joe");  
    p->age = 20;  
      
    return p;   
}  

python

#!/bin/env python  
# coding=UTF-8  
  
from ctypes import *  
  
#python中结构体定义  
class StructPointer(Structure):  
    _fields_ = [("name", c_char * 20), ("age", c_int)]  
  
if __name__ == "__main__":  
    lib = cdll.LoadLibrary("./libmylib.so")  
    lib.testfunction.restype = POINTER(StructPointer)  #指定函数返回值的数据结构
    p = lib.testfunction()  
  
    print "%s: %d" %(p.contents.name, p.contents.age)  

运行结果

[zcm@c_py #112]$make clean  
rm -f *.o libmylib.so 
[zcm@c_py #113]$make  
gcc -g -fPIC -shared -o libmylib.so test.c  
[zcm@c_py #114]$./call.py   
Joe: 20  
[zcm@c_py #115]$ 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×