python调用C/C++程序库,简单易懂含有实例

有时候需要使用python调用已有的C/C++程序库,本文将介绍怎样使用python的ctypes包调用C/C++的方法,并用简单实例进行验证。

首先讲解python调用C程序
例如如下C程序,其中一些输入输出参数貌似不讲道理,但这里是为了说明怎样用python对C程序做好输入输出参数的对接。

// func.c 代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

double* func(double *f, char* str)
{
    
    
   printf("%s\n",str);
   *f=2.4;
   printf("data: %f\n",*f);
   return f;
}

double * const funcArray(double x[], int n)
{
    
    
   for(int i=0;i<n;++i) x[i] = i;
   return x;
}

struct Mystruct
{
    
    
   /* data */
   double * p;
   int ndata;
};
void print(struct Mystruct x){
    
    
   printf("In func print \n");
   for(int i=0;i<x.ndata;++i) printf("%f ",x.p[i]);
   printf("\n");
}

将其编译为动态库

gcc func.c -shared -fPIC -o libfunc.so

接下来开始编写python代码,首先加载libfunc.soC程序库:

from ctypes import *
dll = cdll.LoadLibrary
lib = dll('./libfunc.so')

接下来展示python和C语言之间三类数据的数据交互,包括基本数据类型数组结构体

1. 基本数据类型的数据交互,用double* func(double*, char*)函数来说明

# C程序func函数的返回参数为(double *),所以首先在python中说明返回类型
lib.func.restype = POINTER(c_double) # 返回double *
# int,double,char在python中可以直接用 c_int,c_double等直接定义,但指针类型对象需要用
# byref来获取指针,指针类型的定义需要用POINTER(type)来定义,最后,字符串会特殊一些,需要用到
# create_string_buffer才可以在C程序中进行修改字符串
buf = create_string_buffer('hello world'.encode('gbk')) # 要输入的字符串
data = c_double(1.2) # double类型数据
# 调用函数
res = lib.func(byref(data), buf) #调用函数,参数为 (double*, char *)
# 输出结果
print(buf.value)
print(res[0])

2. 数组的数据交互,用double*const funcArray(double x[],int n)函数来说明

# 首先说明返回类型
lib.funcArray.restype = POINTER(c_double) # 返回为double *
# 关键:定义一个数组
array = c_double *10 # 定义数组
x = array() # 数组空初始化

lib.funcArray(x,10)  # 调用函数,参数为(double x[], int)

for i in range(10):
   print(x[i])

3. 结构体的数据交互,用print(Mystruct s)函数来说明

ndata = 10
# 定义数组类型,用于初始化结构体中的成员变量
array = c_double*ndata

class Mystruct(Structure):
   _fields_=[
      ('p',POINTER(c_double)),
      ('ndata',c_int)
   ]

s = Mystruct()
s.ndata = ndata
s.p = array()
for i in range(s.ndata):
   s.p[i] = i
# 调用C程序函数
lib.print(s)

python对C++程序调用需要先写出C调用C++的接口(可以参考我这篇博客:跳转到博客),然后再按照本文的方法进行调用即可。

猜你喜欢

转载自blog.csdn.net/Meiyuan2021/article/details/129933966