python学习_C语言联合编程

python和C联合编程

python概述

python作为一种胶水语言, 可以封装C语言,Java语言等, 将各个其他语言模块粘合起来,做联合编程.

用C编写一个mymath库给python使用

一,编写C文件

在python import 导入的是C模块,则会调用init函数进行初始化
C文件中加入init入口函数
入口函数中做初始化:


#include 
#include 

int add(int a, int b)
{
	return a+b;
}

void initmymath(void)
{
	Py_InitModule("mymath", NULL);
	printf("init mymath success\n");
	return;
}

注意python3没有Py_InitModule
此处使用python2

二,添加函数

  1. 添加模型方法的结构体数组
struct PyMethodDef method[] = {
	//{"名称",函数指针,函数类型,"使用说明"}
	{"add",mAdd,METH_VARARGS,"this is add func"}
	{"sum",mSum,METH_VARARGS,"this is sum func"}
}; 
  1. 根据需要实现函数
    add函数
#include 
#include 

double add(double a, double b)
{
	return a+b;
}

#include 

static PyObject* mAdd(PyObject* self, PyObject* args)
{
	//判断传输参数个数是否符合
	if( Py_SIZE(args) != 2){return NULL;}
	//获取传入参数
	PyObject *a = PyTuple_GetItem(args,0);
	PyObject *b = PyTuple_GetItem(args,1);
	//判断传入参数类型,若有一个参数不为int或float则返回错误
	if( 
		!(strcmp(Py_TYPE(a)->tp_name, "int") == 0||
		strcmp(Py_TYPE(a)->tp_name, "float") == 0) ||
		!(strcmp(Py_TYPE(b)->tp_name, "int") == 0||
		strcmp(Py_TYPE(b)->tp_name, "float") == 0)
	 )
	 {
		return NULL;
	 }
	 
	 //将参数从PyObject变为double
	 double fa = PyFloat_AsDouble(a);
	 double fb = PyFloat_AsDouble(b);
	 //计算结果
	 double fres = add(fa,fb);
	 
	 //将结果转换为PyObject输出
	 return PyFloat_FromDouble(fres);
}

注意:
- python中所有类型都是PyObject结构类型,使用Py_TYPE(变量)->tp_name即可查看变量的具体类型信息
- python中函数的参数列表实质是元组,使用==PyTuple_GetItem(args,i)==获取参数
- 注意数据类型在具体类型和PyObject之间的转换

sum函数

static PyObject* mSum(PyObject* self, PyObject* args)
{
	int len = Py_SIZE(args);
	PyObject* ob[len];
	double nums[len];
	double fsum=0;
	
	//获取传入参数
	for(int i=0; i<len; ++i)
	ob[i] = PyTuple_GetItem(args,i);
	//判断传入参数类型,若有一个参数不为int则返回错误
	for(int i=0; i<len; ++i)
	if( !(strcmp(Py_TYPE(ob[i])->tp_name, "int") == 0))
	 {
		return NULL;
	 }
	 
	 //将参数从PyObject变为double
	 for(int i=0; i<len; ++i)
	 nums[i] = PyFloat_AsDouble(ob[i]);
	 //计算结果
	 for(int i=0; i<len; ++i)
	 fsum += nums[i];
	 
	 //将结果转换为PyObject输出
	 return PyFloat_FromDouble(fsum);
}
  1. 最后在初始化模型函数中将方法放进去
void initmymath(void)
{
	Py_InitModule("mymath", method);
	printf("init mymath success\n");
	return;
}

三,编写setup.py脚本文件

动态库加入如下:
导入distutils.core文件

from distutils.core import Extension, setup
'.'表示路径,distutils目录下的core
或者
import distutils.core

代码如下

from distutils.core import Extension,setup

module = Extension('mymath',sources = ['mymath.c'])
setup(name = 'mymath', ext_modules = [module])

创建动态库的指令

 python setup.py build # 封装脚本名
 
 sudo python setup.py install #安装动态库
 

主函数测试

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import mymath

c = mymath.add(1,2)
print(c)
c = mymath.sum(1,2,3,4)
print(c) 

输出

init mymath success
3.0
10.0

问题:

fatal error: Python.h: No such file or directory

此时需要确认和下载

sudo apt-get install python3-dev
sudo apt install libpython3.7-dev

或者表示在哪个文件下

#include 
或者
#include 

你可能感兴趣的:(Python学习)