关于Windows实现Python C扩展

本文源自:(1条消息) 浅谈Python C扩展_fitzzhang的博客-CSDN博客_c扩展python

由于不同windows平台上或不同的sw版本, 会出现不同的结果.

本文是使用的环境如下:

 

1. python 3.10

2.swig-4.0.2

3.Visual Studio 2022 Community

Visual Studio: IDE and code editor for software developers and Teams (microsoft.com)

4.window版本 (msc_ver == '1929')

 

正式开始前, 修改的配置点:

1. 确认mingw的环境变量配置
path中添加 C:\MinGW\bin\

2. 确认python的相关环境变量配置

3.添加distutils.cfg
使用C ++编译器选项安装MinGW添加C:\MinGW\bin到您的路径在中PYTHONPATH\Lib\distutils,创建一个文件distutils.cfg并添加以下行:

[build]
compiler = mingw32

4.cygwinccompiler.py 83行后插入

        elif msc_ver == '1700':
            # Visual Studio 2012 / Visual C++ 11.0
            return ['msvcr110']
        elif msc_ver == '1800':
            # Visual Studio 2013 / Visual C++ 12.0
            return ['msvcr120']
        elif msc_ver == '1929':
            # Visual Studio 2015 / Visual C++ 14.0
            # "msvcr140.dll no longer exists" http://blogs.msdn.com/b/vcblog/archive/2014/06/03/visual-studio-14-ctp.aspx
            return ['vcruntime140']

其中msc_ver=='1929'是为了匹配当前的系统版本, 但是动态链接库还是使用vcruntime140, 安装的Visual Studio 2022 Community会包含这部分.

经过上面的准备工作后, 可以进行后续的步骤了.

原文中的代码直接编译会遇到很多问题,经过一番摸索和网络上寻求答案后, 修改如下:

example.cpp源文件

#include <Python.h>

static PyObject* example_mul(PyObject* self, PyObject*args)
{
    float a, b;
    if(!PyArg_ParseTuple(args, "ff", &a, &b))
    {
        return NULL;
    }
    return Py_BuildValue("f", a*b);
}

static PyObject* example_div(PyObject* self, PyObject*args)
{
    float a, b;
    if(!PyArg_ParseTuple(args, "ff", &a, &b))
    {
        return NULL;
    }
    return Py_BuildValue("f", a/b);  // to deal with b == 0
}

static char mul_docs[] = "mul(a, b): return a*b\n";
static char div_docs[] = "div(a, b): return a/b\n";

static PyMethodDef example_methods[] =
{
    {"mul", (PyCFunction)example_mul, METH_VARARGS, mul_docs},
    {"div", (PyCFunction)example_div, METH_VARARGS, div_docs},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef examples = 
{ 
    PyModuleDef_HEAD_INIT, 
    "example", /* 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. */ 
    example_methods 
}; 


PyMODINIT_FUNC PyInit_example(void)
{
    /*Py_InitModule3("example", example_methods, "Extension module example!");*/
	return PyModule_Create(&examples);
}

主要修改点为:Py_InitModule3已经无法找到,所以变异时会报错,替换使用PyModuleDef搭配PyModule_Create, 重命名init  function为PyInit_xxxx(此处已经命名为PyInit_example, 从而可以成功编译.

setup.py源文件

from distutils.core import setup, Extension
setup(name="exampleAPP", version="1.0", ext_modules=[Extension("example", ["example.cpp"])])

注意: setup.py中的Extenson中name(example)一定要和PyInit_xxxx中的xxxx完全一样.

cmd 窗口切换到存放这2个文件的路径, 然后用如下命令编译安装:

python setup.py install --user

添加--user可以规避安装过程中的权限问题.

安装成功后,就会在python_path/Lib/site-packages下面生成example.cp310-win_amd64.pyd这个模块和exampleAPP-1.0-py3.10.egg-info这个文件,就可以导入和使用了

 

开始测试:test_example.py源文件

import example
print('test example start running.\n')
aa = example.mul(5,2)
print(aa)
bb = example.div(5,2)
print(bb)

 运行结果如下

 简单测试可成功.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值