Visual Studio 2013 编译 64 位 Python 的 C 扩展 (使用 PyObject 包装)

Posted Anonymous

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Visual Studio 2013 编译 64 位 Python 的 C 扩展 (使用 PyObject 包装)相关的知识,希望对你有一定的参考价值。

 

对于 32 位 Python 的 C 扩展,以前用过 mingW32 编译,

 

但是 mingW32 不支持 64 位 Python 的 C 扩展编译,详情可见 stackoverflow,这位前辈的大意如下,

 

以下介绍 Visual Studio 2013 编译 64 位 Python 的 C 扩展步骤:

 

1)准备 C 文件和包装文件,

  ExtDemo.c

// Purpose: C code, for wrappered.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int fact(int n)
{
    if(n < 2)
        return 1;
    return n * fact(n - 1);
}

char * reverse(char * s)
{
    char t;
    char *p = s;
    char *q = (s + (strlen(s) - 1));
    
    while(p < q)
    {
        t = *p;
        *p++ = *q;
        *q-- = t;
    }

    return s;
}

// just for unit test, for the two function above
int unit_test(void)
{
    // test fact()
    printf("4! = %d\\n", fact(4));
    printf("8! = %d\\n", fact(8));
    printf("12! = %d\\n", fact(12));

    // test reverse
    char s[10] = "abcdef";
    printf("reversing \'abcdef\', we get \'%s\'\\n", reverse(s));
    char s2[10] = "madam";
    printf("reversing \'madam\', we get \'%s\'\\n", reverse(s2));

    return 0;
}

 

  包装代码 ExtDemo_Wrapper.c

// Purpose: According to the C code, write the Wrapper.

#include "Python.h"

// function declaration

int fact(int n);
char * reverse(char * s);
int unit_test(void);


static PyObject * ED_fact(PyObject * self, PyObject * args)
{
    int num;
    if(!PyArg_ParseTuple(args, "i", &num))
        return NULL;
    return (PyObject *)Py_BuildValue("i", fact(num));
}


static PyObject * ED_reverse(PyObject * self, PyObject * args)
{
    char * orig_str;
    if (!PyArg_ParseTuple(args, "s", &orig_str))
        return NULL;
    return (PyObject *)Py_BuildValue("s", reverse(orig_str));
}

static PyObject * ED_unit_test(PyObject * self, PyObject * args)
{
    unit_test();
    return (PyObject *)Py_BuildValue("");
}

//////////////////////////////////////////////////////////////////////////////

static PyMethodDef EDMethods[] = {
    {"fact", ED_fact, METH_VARARGS, "fact( m )"},   // NOTE, the last string is doc-string of this function
    {"reverse", ED_reverse, METH_VARARGS, "reverse( str )"},
    {"unit_test", ED_unit_test, METH_VARARGS, "unit_test()"},
    {NULL, NULL},
};

//////////////////////////////////////////////////////////////////////////////

void initED()
{
    Py_InitModule("ED", EDMethods);
}

 

  setup.py

#!/usr/bin/env python

from distutils.core import setup, Extension

MOD = \'ED\'
setup(name=MOD, ext_modules=[
    Extension(MOD, sources=[\'ExtDemo.c\', "ExtDemo_Wrapper.c"])])

 

2) Visual Studio 2013 工具准备及编译

  开始菜单打开 Visual Studio Tools 文件夹,

  

 

  选择 64bit Native Tools,双击打开,

  

 

  设置编译环境,如下, 关于这两个参数的含义请参考 distutils.core 官方 help 文档

set DISTUTILS_USE_SDK=1
set MSSdk=1

  

  

  切换到工程目录,编译,

  

 

   编译完成后,在工程目录下生成 build 文件夹,

  

  在其中 \\build\\lib.win-amd64-2.7 下得到编译生成的 pyd 文件,本例为 ED.pyd

  

3) 验证

 

完。

 

以上是关于Visual Studio 2013 编译 64 位 Python 的 C 扩展 (使用 PyObject 包装)的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio Express 2012 或 Express 2013 中是不是提供 64 位编译器?

Qt - Visual Studio 2013 加载项不会编译项目

Visual Studio 2013 /GH /Gh _penter/_pexit 64bit 如何保存寄存器?

Visual Studio 奇怪的异常

无法在 Visual Studio 2008 中构建 Boost.python。编译出错

使用Visual Studio 2013 For Java