首先我觉得最重要的了解途径肯定是看官方文档https://docs.python.org/2/library/ctypes.html
其次就是看川哥的不断试错。
首先python调用c程序,是需要加载共享库。
首先我们来看看共享库在《Linux程序设计》的定义:
连接方式:程序本身不包含函数代码,而是引用运行时可访问的共享代码。当编译好的程序被装载到内存中执行时,函数引用被解析并产生对共享库的调用,如有必要,共享库才会被加载到内存中。
下面我会给出一个例子来讲解一般的传参和解析返回数据的用法。
首先我们给出C代码:
#include <stdio.h>
#include <stdlib.h>
struct structImg
{
int width;
int height;
int channels;
unsigned char * buf;
};
extern "C"
{
void showStructureInfo(structImg p);
char * getSturctureInfo();
char test();
}
void showStructureInfo(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]);
}
char * getSturctureInfo() {
return "hello world";
}
然后执行下面的命令
g++ -std=c++11 -shared -fPIC -o libstructPoint.so main.cpp
会生成一个叫做libstructPoint.so的共享库
然后我们给出python代码:
from ctypes import *
lib = cdll.LoadLibrary('libstructPoint.so')
class structImgTest(Structure):
_fields_ =[('width', c_int),
('height', c_int),
('channels', c_int),
('buf', POINTER(c_ubyte))]
def getstructImg(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 in range(num):
data_buf[i] = i
pbuf = cast(data_buf, POINTER(c_ubyte))
st = structImgTest(width, height, channels, pbuf)
return st
#获取函数返回的char *
lib.getSturctureInfo.restype = POINTER(c_ubyte)
info = lib.getSturctureInfo()
print(chr(info[0]))
# 传入一个结构体
st = getstructImg(3, 3, 3)
lib.showStructureInfo(st)
本文章参考了不少其他同志写的。
然后最重要的一点还是,传入的参数如果需要的是指针需要用POINTER函数,如果是其它变量可以使用c_int之类的。