python调用c语言接口_(原)python使用ctypes调用C/C++接口

转载请注明出处:

参考网址:

importImagefrom ctypes importc_ubyte, cast, POINTER

buf= (c_ubyte * 400)()

pbuf=cast(buf, POINTER(c_ubyte))

pbuf2= cast(pbuf, POINTER(c_ubyte*400))

buf is an ubyte array, pbuf is a pointer to ubyte, pbuf2 is a pointer to ubyte[400]. img1 is created from buf directly, img2 is created from pubf2.contents.

一 传简单的指针:

具体步骤:

1. 新建mathBuf.cpp:

#include #include"subBuf.h"

extern "C"{int addBuf(char* data, int num, char*outData);

subBuf* subBuf_new(){ return newsubBuf(); }int subBuf_sub(subBuf* subfuf, char* data, int num, char* outData){ subfuf->cursubBuf(data, num, outData); }

}int addBuf(char* data, int num, char*outData)

{for (int i = 0; i < num; ++i)

{

outData[i]= data[i] + 3;

}returnnum;

}

2. 新建subBuf.h:

#include

classsubBuf{public:

subBuf(){}int cursubBuf(char* data, int num, char*outData)

{for (int i = 0; i < num; ++i)

{

outData[i]= data[i] - 5;

}returnnum;

}

};

3. 终端中输入如下命令,生成libmathBuf.so:

g++ -std=c++11 -shared -fPIC -o libmathBuf.so mathBuf.cpp

4. 新建test.py:

from ctypes import * #cdll, c_int

lib = cdll.LoadLibrary('libmathBuf.so')classcallsubBuf(object):def __init__(self):

self.obj=lib.subBuf_new()defcallcursubBuf(self, data, num, outData):

lib.subBuf_sub(self.obj, data, num, outData)

callAddBuf=lib.addBuf

num= 4numbytes=c_int(num)

data_in= (c_byte *num)()for i inrange(num):

data_in[i]=iprint("initial input data buf:")for i inrange(num):print(data_in[i])#pdata_in = cast(data_in, POINTER(c_ubyte))#pdata_in2 = cast(pdata_in, POINTER(c_ubyte*num))

data_out= (c_byte *num)()

ret=callAddBuf(data_in, numbytes, data_out)print("after call addBuf with C, output buf:")for i inrange(num):print(data_out[i])

f=callsubBuf()

f.callcursubBuf(data_in, numbytes, data_out)print("after call cursubBuf with C++ class, output buf:")for i inrange(num):print(data_out[i])

5. 运行test.py,输出如下:

682463-20161205210500257-1923788334.png

说明:

1) test.py如果使用c_byte,则对应C中的unsigned char。

2) 程序使用了2个文件,subBuf.h和mathBuf.cpp。实际上可以使用一个文件,但是class要在extern "C"的上面,否则即便声明了class subBuf,也会提示invalid use of incomplete type ‘class subBuf’:

682463-20161205210515288-1257931042.png

3) addSub函数的实现要在extern "C"的下面,否则会提示error: conflicting declaration of XXX with ‘C’ linkage:

682463-20161205210530054-250184372.png

4) ctypes中对应的c和python类型如下(具体参见ctypes的官方文档):

ctypes type

C type

Python type

c_bool

_Bool

bool (*)

c_char

char

1-character string

c_wchar

wchar_t

1-character unicode string

c_byte

char

int/long

c_ubyte

unsigned char

int/long

c_short

short

int/long

c_ushort

unsigned short

int/long

c_int

int

int/long

c_uint

unsigned int

int/long

c_long

long

int/long

c_ulong

unsigned long

int/long

c_longlong

__int64 or long long

int/long

c_ulonglong

unsigned __int64 or unsigned long long

int/long

c_float

float

float

c_double

double

float

c_longdouble

long double

float

c_char_p

char * (NUL terminated)

string or None

c_wchar_p

wchar_t * (NUL terminated)

unicode or None

c_void_p

void *

int/long or None

*. The constructor accepts any object with a truth value.

5) 除此之外:

提供了使用void*传递缓冲区的简单说明。

二 传结构体

1. 新建structPoint.cpp:

#include #include

structstructImg

{intwidth;intheight;intchannels;char*buf;

};extern "C"{voidshowStructureInfo(structImg p);

}voidshowStructureInfo(structImg p)

{

printf("%d %d %d\n", p.width, p.height, p.channels);for(int i=0;i< p.width*p.height*p.channels; ++i)

printf("%d: %d\n", i, p.buf[i]);

}

2. 终端中将该文件编译成.so库:

g++ -std=c++11 -shared -fPIC -o libstructPoint.so structPoint.cpp

3. 新建test.py:

from ctypes import *lib= cdll.LoadLibrary('libstructPoint.so')classstructImgTest(Structure):

_fields_=[('width', c_int),

('height', c_int),

('channels', c_int),

('buf', POINTER(c_ubyte))]defgetstructImg(width, height, channels):#cwidth = c_int(width)

#cheight = c_int(height)

#cchannels = c_int(channels)

num = width * height *channels

data_buf= (c_byte *num)()for i inrange(num):

data_buf[i]=i

pbuf=cast(data_buf, POINTER(c_ubyte))

st=structImgTest(width, height, channels, pbuf)returnst

width= 4height= 3channels= 2st=getstructImg(width, height, channels)

callTest=lib.showStructureInfo

callTest(st)printst.widthprintst.height#if declaration of test is test(structImg* p), then use the following line

pst = pointer(st) #not sure if "POINTER" points to ctypes type, while "pointer" points to a variable

printpst.contents.widthprint pst.contents.height

4. 终端中运行test.py,结果如下:

682463-20161206152028319-785698287.png

可见输出的结果正确。

=========================================================================

190130更新:

下面两个网址有使用ctypes的比较详细的说明,也可以参考一下。

190130更新结束

=========================================================================

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值