python与ctypes的爱恨情仇(传参和获取结果)

首先我觉得最重要的了解途径肯定是看官方文档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之类的。

猜你喜欢

转载自blog.csdn.net/qq_20949153/article/details/83212255