本系列将介绍如何用C/C++扩展Python模块,使用C语言编写Python模块,添加到Python中作为一个built-in模块。Python与C之间的交互目前有几种方案:

1. 原生的Python C/C++ API, 官网有非常详细的文档说明

2. boost python,一个C++的编程框架,对官方API进行了封装,可以方便的用C++扩展Python模块,省去了很多诸如引用计数的烦恼。 http://www.boost.org/doc/libs/1_64_0/libs/python/doc/html/index.html

3. Cython. Cython其实是一个可以优化Python程序的编译器,将Python代码翻译成C代码,然后使用C/C++编译器进行编译得到pyd(windows)或so(linux),在Python解释器中可以直接import。这种方法里面的坑有点多,在本系列博客中会介绍到Cython。   http://cython.org/

4. 谷歌最近开源的CLIF项目,同时支持Python2和Python3,目前来说还不太完善。  https://github.com/google/clif

其他的框架。。。。。。

本篇将介绍如何用官方提供的Python C/C++ API来扩展Python模块。工欲善其事必先利其器,先讲一下如何搭建开发环境(默认已经安装了Python)。以下为【DEBUG】版的配置:

1. Python版本: Python2.7 32位;   操作系统: Windows7;  IDE: Visual Studio 2015。

2. 配置Library Directories、Additional Include Directories、Link Input

3. 写一段hello world程序 ,先不纠结语法细节

[test.c]

#include <Python.h>

static PyMethodDef test_methods[] = { NULL, NULL, , NULL };

PyMODINIT_FUNC test_init(void)
{
Py_InitModule3("test", test_methods, "Common test Written in C.");
}

[Souce.cpp]

#include <Python.h>

PyMODINIT_FUNC test_init();

int main()
{
Py_Initialize();
test_init();
return ;
}

然后编译,很大可能会出现Link时找不到解析符号以及无法找到python27_d.lib,这主要是pyconfig.h里代码的一些宏导致的。

1)找到python2.7/include/pyconfig.h,并找到

#ifdef _DEBUG
#define Py_DEBUG
#endif

修改为

#ifdef _DEBUG
//#define Py_DEBUG
#endif

2)Configuration Properties->C/C++->Preprocessor->Preprocessor Definitions添加MS_NO_COREDLL或Py_NO_ENABLE_SHARED

原因解释:

1)

在pyconfig.h中:

#ifdef _DEBUG
#define Py_DEBUG
#endif

在object.h中有以下定义:

/* Py_DEBUG implies Py_TRACE_REFS. */
#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
#define Py_TRACE_REFS
#endif

在modesupport.h中

#ifdef Py_TRACE_REFS
/* When we are tracing reference counts, rename Py_InitModule4 so
modules compiled with incompatible settings will generate a
link-time error. */
#if SIZEOF_SIZE_T != SIZEOF_INT
#undef Py_InitModule4
#define Py_InitModule4 Py_InitModule4TraceRefs_64
#else
#define Py_InitModule4 Py_InitModule4TraceRefs
#endif
#endif

所以当定义了Py_DEBUG,就会导致Py_InitModule4重命名为Py_initModule4TraceRefs,而lib中没有此符号,所以导致了链接错误。故而注释掉#define Py_DEBUG这一行即可。

2)找不到python27_d.lib问题

同样在pyconfig.h中:

/* For Windows the Python core is in a DLL by default.  Test
Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
#if !defined(MS_NO_COREDLL) && !defined(Py_NO_ENABLE_SHARED)
# define Py_ENABLE_SHARED /* standard symbol for shared library */
# define MS_COREDLL /* deprecated old symbol */
#endif /* !MS_NO_COREDLL && ... */ /* All windows compilers that use this header support __declspec */
#define HAVE_DECLSPEC_DLL /* For an MSVC DLL, we can nominate the .lib files used by extensions */
#ifdef MS_COREDLL
# ifndef Py_BUILD_CORE /* not building the core - must be an ext */
# if defined(_MSC_VER)
/* So MSVC users need not specify the .lib file in
their Makefile (other compilers are generally
taken care of by distutils.) */
# ifdef _DEBUG
# pragma comment(lib,"python27_d.lib")
# else
# pragma comment(lib,"python27.lib")
# endif /* _DEBUG */
# endif /* _MSC_VER */
# endif /* Py_BUILD_CORE */
#endif /* MS_COREDLL */

可以看到如果没有定义MS_NO_COREDLL和Py_NO_ENABLE_SHARED时,会定义MS_COREDLL,然后在DEBUG模式下会加载python27_d.lib。所以在Preprocessor Definitions中定义MS_NO_COREDLL即可解决。

4. 编译&链接错误解决之后,可以正常运行。

上面的例子中,test.c定义了一个模块test,在Source.cpp中初始化了该模块。下一节将用一个例子来详细介绍使用Python C/C++ API扩展Python模块。

扩展Python模块系列(一)----开发环境配置的更多相关文章

  1. 扩展Python模块系列(二)----一个简单的例子

    本节使用一个简单的例子引出Python C/C++ API的详细使用方法.针对的是CPython的解释器. 目标:创建一个Python内建模块test,提供一个功能函数distance, 计算空间中两 ...

  2. 扩展Python模块系列(四)----引用计数问题的处理

    承接上文,发现在使用Python C/C++ API扩展Python模块时,总要在各种各样的地方考虑到引用计数问题,稍不留神可能会导致扩展的模块存在内存泄漏.引用计数问题是C语言扩展Python模块最 ...

  3. 扩展Python模块系列(五)----异常和错误处理

    在上一节中,讨论了在用C语言扩展Python模块时,应该如何处理无处不在的引用计数问题.重点关注的是在实现一个C Python的函数时,对于一个PyObject对象,何时调用Py_INCREF和Py_ ...

  4. 扩展Python模块系列(三)----参数解析与结果封装

    在上一节中,通过一个简单的例子介绍了C语言扩展Python内建模块的整体流程,从本节开始讲开始深入讨论一些细节问题,在细节讨论中从始至终都会涉及[引用计数]的问题.首先讨论C语言封装的Python函数 ...

  5. UPUPW Apache5.5系列本地开发环境配置

    UPUPW Apache5.5系列 1. 在官网下载 Apache5.5系列,选择云端下载. 官网地址: http://www.upupw.net/aphp55/n110.html 2. 下载后,将压 ...

  6. Python在Windows下开发环境配置汇总

    最近比较关注学习Python方面的资料和课程,由于Python本身基本都是在Linux下开发,本人windows用习惯了初用Linux各种别扭啊. 下面将我在配置Windows环境下的禁言写出来,与大 ...

  7. VS2015下的Android开发系列01——开发环境配置及注意事项

    概述 VS自2015把Xamarin集成进去后搞Android开发就爽了,不过这安装VS2015完成的时候却是长了不知道多少.废话少说进正题,VS2015安装时注意把Android相关的组件勾选安装, ...

  8. Django的基本开发环境配置和MTV模型

    一.MTV模型 Django的MTV分别代表: Model(模型):负责业务对象与数据库的对象(ORM) Template(模版):负责如何把页面展示给用户 View(视图):负责业务逻辑,并在适当的 ...

  9. PHP开发环境配置系列(四)-XAMPP常用信息

    PHP开发环境配置系列(四)-XAMPP常用信息 博客分类: PHP开发环境配置系列 xamppphp 完成了前面三篇后(<PHP开发环境配置系列(一)-Apache无法启动(SSL冲突)> ...

随机推荐

  1. 1.如何安装maven

    [确认]在CMD命令行中输入echo %JAVA_HOME%,查看JAVA_HOME是否配置.在CMD命令行中输入java -v,查看jdk是否正确安装.   [下载]从http://maven.ap ...

  2. 手机端 图片的移动缩放旋转兼容touch

    //缩放var initialScale = 1;var currentScale = 1;touch.on('#target', 'pinch', function (ev) { currentSc ...

  3. ASP.NET 导出EXCEL文件处理多对应排列的

    这次项目遇到了一个导出excel需要对应排列的问题.本来在做这个项目之前都基本没做过excel导出的菜鸡,这次强行做还是有些忐忑的,加上那个表的结构比较奇特.    废话不多说,先介绍表结构吧 是数据 ...

  4. python迭代器生成器(三)

    扩展的列表解析语法 今天接着昨天的继续写. 列表解析可以变得更加复杂---例如,它可以包含嵌套的循环,也可能被编写为一系列的for子句.(这里只是简单介绍一下,以后再说这个语法的问题) 例如:构建一个 ...

  5. 读书共享 Primer Plus C-part 8

    第十三章 文件输入/输出 fopen--fclose fopen 是文件的操作的开始 fclose是文件操作的结束 getc--putc getchar--putchar getc对应文件的获取单个字 ...

  6. Maven-FAQ

    1.Failure to transfer org.apache.maven.plugins:maven-resources-plugin:pom:2.5...: Q: 第一次使用maven+ecli ...

  7. Android源码博文集锦2

    Android精选源码 android简单易用的Gallery android漂亮的加载效果 这可能是RxJava 2.x 最好的入门教程示例代码 android图片可拖拽排序 android用几行代 ...

  8. Linux 下搭建www服务器

    偶然的机会接触了前端开发,尽管最初的意愿是后台. 不过现在看来,前端后台数据库密不可分! 回想起来感觉自己学习的层次也还很好,因为之前有学习c语言.c++的基础,所以在学习html,js的过程中感觉还 ...

  9. PHP面向对象 ——多态

    接口 接口(interface)是抽象方法和静态常量定义的集合. 接口是一种特殊的抽象类,这种抽象类中只包含抽象方法和静态常量. 接口中没有其它类型的内容 接口的定义 /** * 接口可以认为是特殊的 ...

  10. jvm007 jvm知识点总览

    转载来自:http://www.ityouknow.com/ 在江湖中要练就绝世武功必须内外兼备,精妙的招式和深厚的内功,武功的基础是内功.对于武功低(就像江南七怪)的人,招式更重要,因为他们不能靠内 ...