VS2013 Python3.5.3 编写C扩展库

来源:互联网 发布:山东烟台正浩网络 编辑:程序博客网 时间:2024/06/03 19:02

      最近再学习如何在python中编写C扩展库,搜索网上很多帖子和博文都是基于python2.7,按照这些文章,尝试了很多遍仍然有各种各样的问题。  现将能够运行的一个小测试案例进行整理

运行平台 VS2013 旗舰版   python3.5.3  pycharm2017.1.1

       编写扩展库需要包括三个部分:1 导入导函数及功能函数实现     2 方法描述    3 初始化函数

首先你需要在VS中建立一个DLL工程并设置如下几个最关键的内容

配置环境为x64,在程序中加入如下预编译

#include "stdafx.h"#include <Python.h>


对环境进行配置

注意:其中的输出目录一定要设置到python安装文件下的DLLS文件夹 目标文件扩展名改为.pyd  配置类型改为动态库(.dll)


设置包含目录为python安装目录下的include文件夹


设置添加库目录为python安装目录下的libs文件夹,这里由于很多人没哟python35_d.lib这个文件,所以你需要在官网上下载Python-3.5.3.tgz然后进行编译生成,这里不做详细说明,大家参考这位大神的博客

 http://blog.163.com/danshiming@126/blog/static/1094127482016525415131/ 

我使用的方法是直接改pytconfig.h文件

但显然这种方法是治标不治本。


在其他选项栏里头添加/export:Pyinit_PyExt  (初始化方法名,和程序对应起来)

//第一步:方法描述 如下函数实现了幂运算
int fact(int n){if (n <= 1) return 1;elsereturn n * fact(n - 1);}
//对于这个功能函数需要编写一个对应的导入函数作为python数据和C数据的接口
PyObject* wrap_fact(PyObject* self, PyObject* args){ int n, result; if (!PyArg_ParseTuple(args, "i:fact", &n))//用于将python数据带入,并传递给C函数中的变量n  return NULL; result = fact(n);//对n的值进行幂运算 return Py_BuildValue("i", result);//将结果转换成python的数据类型并以pyobject型指针返回}
//第二步:方法列表 
static PyMethodDef PyExtMethods[] ={ { "fact", wrap_fact, METH_VARARGS, "Caculate N!" }, { NULL, NULL }};
static struct PyModuleDef PyExt_module = { PyModuleDef_HEAD_INIT, "PyExt",            // name of module  NULL,       //module documentation, may be NULL  -1,           // size of per-interpreter state of the module, or -1 if the module keeps state in global variables. PyExtMethods   // A pointer to a table of module-level functions, described by PyMethodDef values. Can be NULL if no functions are present.};
//这里定义了一个模型PyExt_module用于初始化python3.5使用的初始化函数是PyModule_Create,而python2.7则直接使用函数Py_InitModule进行初始化.我使用的是pyt//hon3.5所以定义的初始化函数如下
//第三步:初始化函数
PyMODINIT_FUNC PyInit_PyExt(void){ PyObject *m; m = PyModule_Create(&PyExt_module); if (m == NULL)  return NULL; printf("init pyext module\n"); return m;}
//注意 当你使用pthon2.7的时候 初始化函数的形式如下,除了使用的初始化函数不一样,对于命名,python2.7要求为init +模块名 而python3.5要求为PyInit_ +模块名PyMODINIT_FUNC initPythonDemo(void)  {Py_InitModule("PyExt",PyExtMethods);
然后右键点击项目生成动态链接库,此时会发现python安装目录下的DLLS文件夹下多了如下几个文件
PyExt.lib PyExt.pyd PyExt.exp
然后在python中编写如下测试程序
import PyExtresult = PyExt.fact(3)print(result)print("ok")

观察打印窗口会出现如下信息

证明输出的结果为所求3!=6

到此结束

参考博文:

http://blog.csdn.net/catalyst_zx/article/details/47333909

http://blog.csdn.net/little_tan/article/details/53457011

http://www.jianshu.com/p/cd28e8b0cce1

官方文档

https://docs.python.org/3.5/howto/cporting.html?highlight=py_initmodule

 
原创粉丝点击