場合によっては、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.so
C ライブラリをロードします。
from ctypes import *
dll = cdll.LoadLibrary
lib = dll('./libfunc.so')
基本数据类型
次に、Python と C 言語間の、数组
、の 3 種類のデータのデータ相互作用を示します结构体
。
double* func(double*, char*)
1.関数によって説明される基本的なデータ型のデータ相互作用
# 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 のインターフェイスを記述し (私のブログを参照してください:ブログへジャンプ)、次にこの記事の方法に従ってそれを呼び出す必要があります。