zoukankan      html  css  js  c++  java
  • 扩展Python模块系列(一)----开发环境配置

        本系列将介绍如何用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, 0, 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 0;
    }

    然后编译,很大可能会出现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 1 /* 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模块。

    作者: 建木
    出处: http://www.cnblogs.com/jianmu/
    本文版权归作者和博客园所有,如有转载,需注明出处。

  • 相关阅读:
    CocoaPods 安装教程
    iOS 如何使用第三方字库
    iOS 获取当前网络状态
    GitHub上README.md教程
    如何获取iOS软件包内容
    iOS中如何监测来电
    OS 如何选择delegate、notification、KVO?
    iOS-Block总结 && 全面解析逆向传值
    iOS面试题
    iOS优秀博客收录
  • 原文地址:https://www.cnblogs.com/jianmu/p/7345224.html
Copyright © 2011-2022 走看看