• Windows下使用Visual Code编写并编译基于C的Python插件


    背景

    当你在使用Python的过程中发现,现有的功能满足不了你的需求(通常是业务,或者执行效率),这个时候如果你有C语言编程的能力,

    是否想过写单独的插件来优化你所需的功能呢,本文的背景正式基于此,本文的开发环境是,Windows10 64位,Visual C++(Visual Studio 2019)

    开发工具:Visual Code, Python版本是:Python3.10.amd64,其中Python安装环境是:d:\develop\python\Python310。

    本文讲述的是使用C语言中的fputs写Cpyhton的插件提供Python使用,用以保存文件。

    1、C代码

    fputsmodule.c

    #include <Python.h>
    //https://realpython.com/build-python-c-extension-module/#considering-alternatives
    static PyObject *StringTooShortError = NULL;
    static PyObject *method_fputs(PyObject *self, PyObject *args) { char *str, *filename = NULL; int bytes_copied = -1; /* Parse arguments */ if(!PyArg_ParseTuple(args, "ss", &str, &filename)) { return NULL; } if (strlen(str) < 10) { /* Passing custom exception */ PyErr_SetString(StringTooShortError, "String length must be greater than 10"); return NULL; } FILE *fp = fopen(filename, "w"); bytes_copied = fputs(str, fp); fclose(fp); return PyLong_FromLong(bytes_copied); } static PyMethodDef FputsMethods[] = { {"fputs", method_fputs, METH_VARARGS, "Python interface for fputs C library function"}, {NULL, NULL, 0, NULL} }; static struct PyModuleDef fputsmodule = { PyModuleDef_HEAD_INIT, "fputs", "Python interface for the fputs C library function", -1, FputsMethods }; PyMODINIT_FUNC PyInit_fputs(void) { /* Assign module value */ PyObject *module = PyModule_Create(&fputsmodule); /* Add int constant by name */ PyModule_AddIntConstant(module, "FPUTS_FLAG", 64); /* Define int macro */ #define FPUTS_MACRO 256 /* Add macro to module */ PyModule_AddIntMacro(module, FPUTS_MACRO); /* Initialize new exception object */ StringTooShortError = PyErr_NewException("fputs.StringTooShortError", NULL, NULL); /* Add exception object to your module */ PyModule_AddObject(module, "StringTooShortError", StringTooShortError); return module; }

    2、编译用脚本

    setup.py

    from distutils.core import setup, Extension
    
    def main():
        setup(name="fputs",
              version="1.0.0",
              include_dirs="d:/develop/python/Python310/include",
              description="Python interface for the fputs C library function",
              author="<your name>",
              author_email="your_email@gmail.com",
              ext_modules=[Extension("fputs", ["fputsmodule.c"])])
    
    if __name__ == "__main__":
        main()

    3、编译及安装

    PS E:\project\python\extends1> python.exe .\setup.py build
    E:\project\python\extends1\setup.py:1: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. 
    Use setuptools or check PEP 632 for potential alternatives from distutils.core import setup, Extension running build running build_ext building 'fputs' extension C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL
    /DNDEBUG /MD -Id:/develop/python/Python310/include -ID:\develop\python\Python310\include -ID:\develop\python\Python310\Include
    -IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\include
    -IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt
    -IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared
    -IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um
    -IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt
    -IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt /Tcfputsmodule.c /Fobuild\temp.win-amd64-3.10\Release\fputsmodule.obj fputsmodule.c C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\link.exe
    /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO
    /LIBPATH:D:\develop\python\Python310\libs /LIBPATH:D:\develop\python\Python310\PCbuild\amd64
    /LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\lib\x64
    /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x64
    /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x64
    /EXPORT:PyInit_fputs build\temp.win-amd64-3.10\Release\fputsmodule.obj
    /OUT:build\lib.win-amd64-3.10\fputs.cp310-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.10\Release\fputs.cp310-win_amd64.lib 正在创建库 build\temp.win-amd64-3.10\Release\fputs.cp310-win_amd64.lib 和对象 build\temp.win-amd64-3.10\Release\fputs.cp310-win_amd64.exp 正在生成代码 已完成代码的生成 PS E:\project\python\extends1> python.exe .\setup.py install E:\project\python\extends1\setup.py:1: DeprecationWarning: The distutils package is deprecated and slated for
    removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives from distutils.core import setup, Extension running install running build running build_ext running install_lib copying build\lib.win-amd64-3.10\fputs.cp310-win_amd64.pyd -> D:\develop\python\Python310\Lib\site-packages running install_egg_info Removing D:\develop\python\Python310\Lib\site-packages\fputs-1.0.0-py3.10.egg-info Writing D:\develop\python\Python310\Lib\site-packages\fputs-1.0.0-py3.10.egg-info PS E:\project\python\extends1> D:\develop\python\Python310\python.exe .\py_fputs.py Real Python! PS E:\project\python\extends1>

    4、运行

    测试脚本1:
    import fputs
    print(fputs.__doc__)
    
    print(fputs.__name__)
    
    # Write to an empty file named `write.txt`
    fputs.fputs("Real Python!", "write.txt")
    
    with open("write.txt", "r") as f:
        print(f.read())

    执行效果:

    PS E:\project\python\extends1> D:\develop\python\Python310\python.exe .\py_fputs.py
    Python interface for the fputs C library function
    fputs
    Real Python!
    PS E:\project\python\extends1>

    测试脚本2:保存字符长度小于10个字符(触发字符内容长度小于10的报错)

    import fputs
    print(fputs.__doc__)
    
    print(fputs.__name__)
    
    # Write to an empty file named `write.txt`
    fputs.fputs("Real", "write.txt")
    
    with open("write.txt", "r") as f:
        print(f.read())

    执行效果

    Traceback (most recent call last):
      File "E:\project\python\extends1\py_fputs.py", line 7, in <module>
        fputs.fputs("Real", "write.txt")
    fputs.StringTooShortError: String length must be greater than 10

    参考来源:Building a Python C Extension Module – Real Python

  • 相关阅读:
    在windows上使用win2000资源工具
    Apache与Tomcat整合
    web服务器和应用服务器概念比较
    linux定时删除N天前的文件(文件夹)
    程序员如何自我学习和成长?
    20210708总结
    Docker 常用命令!还有谁不会?
    Redis常用命令set
    laravel与thinkphp之间的区别与优缺点
    2021年7月总结
  • 原文地址:https://www.cnblogs.com/passedbylove/p/16756063.html
Copyright © 2020-2023  润新知