背景
当你在使用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
本博客文章绝大多数为原创,少量为转载,代码经过测试验证,如果有疑问直接留言或者私信我。
创作文章不容易,转载文章必须注明文章出处;如果这篇文章对您有帮助,点击右侧打赏,支持一下吧。
创作文章不容易,转载文章必须注明文章出处;如果这篇文章对您有帮助,点击右侧打赏,支持一下吧。