您的位置:首页 > 编程语言 > Python开发

Python3 C扩展

2016-12-04 22:48 309 查看
最近在看Python核心编程,感觉真的是简洁而强大,而且支持各种语言的扩展。网上找到的C扩展例子差不多都是在Mac或者Linux下的,下面整理下Python3.x在windows vs2012的C扩展吧。希望可以帮助到其他人~
1、VS环境配置

需要在cmd上执行一些命令,所以要配置一下VS的运行环境(测试下环境是否可用:在cmd上输入cl,如果如下图所示那就跳过这步)



打开环境变量编辑,添加变量VS_2012=(VS安装目录),然后在PATH后面加上(仔细对下定义的路径是否存在)

;%VS_2012%\Common7\IDE;%VS_2012%\Common7\Tools;%VS_2012%\VC\bin;%VS_2012%\VC\vcpackages;C:\Windows\Microsoft.NET\Framework64\v4.0.30319;C:\Windows\Microsoft.NET\Framework64\v3.5;C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\Windows\Microsoft.NET\Framework\v3.5;

配置完之后确定,重新打开cmd,测试环境是否正常。

2、python环境

这里使用的是3.x的python

cmd里面输入Python --version可查看python的版本信息(提示错误的话,那重装吧,我也不知道为啥。。。)

3、编写C扩展程序

按照书上写的,不过那是2.x版本的,我改了下,变成了3.x的啦,如下~

 Extest2.c

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

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

char *reverse(char *s)
{
register char t,
*p = s,
*q = (s + (strlen(s) - 1));

while (s && p < q)
{
t = *p;
*p++ = *q;
*q-- = t;
}
return s;
}

int test()
{
char s[1024] = {0};
printf("4! == %d\n", fac(4));
printf("8! == %d\n", fac(8));
printf("12! == %d\n", fac(12));
strcpy_s(s, 1024, "abcdef");
printf("reversing 'abcdef', we get '%s'\n", reverse(s));
strcpy_s(s, 1024, "madam");
printf("reversing 'madam', we get '%s'\n", reverse(s));
return 0;
}

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

static PyObject* Extest_doppel(PyObject *self, PyObject *args)
{
char *orig_str;
char *dupe_str;
PyObject *retval;
if (!PyArg_ParseTuple(args, "s", &orig_str))
{
return NULL;
}

retval = (PyObject*)Py_BuildValue("ss", orig_str, dupe_str=reverse(_strdup(orig_str)));
free(dupe_str);
return retval;
}

static PyObject* Extest_test(PyObject *self, PyObject *args)
{
test();
return (PyObject*)Py_BuildValue("");
}

static PyMethodDef ExtestMethods[] =
{
{"fac", Extest_fac, METH_VARARGS, "fac func"},
{"doppel", Extest_doppel, METH_VARARGS, "reverse str"},
{"test", Extest_test, METH_VARARGS, "test func"},
{NULL, NULL, 0, NULL},
};

static struct PyModuleDef ExtestMoudle =
{
PyModuleDef_HEAD_INIT,
"Extest",
NULL,
-1,
ExtestMethods
};

void PyInit_Extest()
{
PyModule_Create(&ExtestMoudle);
}


还有setup.py

# -*- coding: UTF-8 -*-

from distutils.core import setup, Extension

MOD = 'Extest'
setup(name=MOD, ext_modules=[Extension(MOD, sources=['Extest2.c'])])


4、编译

cd到代码所在的文件夹,键入: python setup.py build

(这里编译应该是出问题的,3.x默认的VS版本是2015,而我的是2012,不出意外会提示成下面的错误)



别着急,打开Python35\Lib\distutils\_msvccompiler.py这个文件,找到“Unable to find vcvarsall.bat”这个字符串在哪里,不难发现如下的代码

if version >= 14 and version > best_version:

这就是检查了vs的版本的代码,备份下这个文件,然后把14改小点(至于改小多少,你就猜吧。。。)或者直接注释掉这行代码(记得把下面那行往前删掉一个tab哈)

再在cmd键入:python setup.py build   不出意外应该好了的。



先别急着关掉,再键入: python setup.py install

将编译的东西安装到Python里面(可能这么描述不太对,其实我是真的不懂怎么描述。。。),Python35\Lib\site-packages这个文件夹里面会多了Extest开头的两个文件

5、测试

Extest.py

# encoding: utf-8

import Extest

Extest.test()

 

执行这个文件或者调用Extest里面导出函数fac doppel test,看看结果如何吧。



 

就当做记录下学python的过程吧~~欢迎多多交流~~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息