如何将Python代码转换为Windows平台的.dll文件(非.pyd)
将Python代码转换为Windows DLL(非.pyd)的可行方法
PyInstaller本身仅支持生成可执行文件(.exe),要生成标准Windows动态链接库(.dll),可以采用以下两种可靠方案:
方案一:通过C++包装Python代码编译为.dll
利用Python C API编写包装层,将Python函数暴露为C风格的导出函数,再通过MSVC或MinGW编译成.dll。
步骤示例
编写Python模块
比如创建test.py,包含需要暴露的函数:def add(a, b): return a + b def greet(name): return f"Hello, {name}!"编写C++包装代码
创建wrapper.cpp,通过Python C API调用Python模块的函数,并导出为C接口:#include <Python.h> // 导出add函数,采用C调用约定 extern "C" __declspec(dllexport) int __cdecl add(int a, int b) { Py_Initialize(); // 添加当前路径到Python搜索路径,确保能找到test.py PyRun_SimpleString("import sys; sys.path.insert(0, '.')"); PyObject* pModule = PyImport_ImportModule("test"); PyObject* pFunc = PyObject_GetAttrString(pModule, "add"); PyObject* pArgs = PyTuple_New(2); PyTuple_SetItem(pArgs, 0, PyLong_FromLong(a)); PyTuple_SetItem(pArgs, 1, PyLong_FromLong(b)); PyObject* pResult = PyObject_CallObject(pFunc, pArgs); int result = PyLong_AsLong(pResult); // 清理Python对象,避免内存泄漏 Py_DECREF(pArgs); Py_DECREF(pFunc); Py_DECREF(pModule); Py_DECREF(pResult); Py_Finalize(); return result; } // 导出greet函数 extern "C" __declspec(dllexport) const char* __cdecl greet(const char* name) { Py_Initialize(); PyRun_SimpleString("import sys; sys.path.insert(0, '.')"); PyObject* pModule = PyImport_ImportModule("test"); PyObject* pFunc = PyObject_GetAttrString(pModule, "greet"); PyObject* pArgs = PyTuple_New(1); PyTuple_SetItem(pArgs, 0, PyUnicode_FromString(name)); PyObject* pResult = PyObject_CallObject(pFunc, pArgs); const char* result = PyUnicode_AsUTF8(pResult); // 注意:这里返回的字符串是Python内部内存,若需要长期使用需自行拷贝 Py_DECREF(pArgs); Py_DECREF(pFunc); Py_DECREF(pModule); Py_DECREF(pResult); Py_Finalize(); return result; }编译生成.dll
使用MSVC的cl命令编译(需先配置MSVC环境变量):cl /LD /I"C:\Python311\include" /link /LIBPATH:"C:\Python311\libs" wrapper.cpp python311.lib替换路径为你的Python安装目录,
python311.lib对应Python 3.11版本,需匹配你的Python版本。
方案二:使用Nuitka直接生成.dll
Nuitka是一款Python编译工具,可将Python代码编译为C代码,并直接生成标准Windows .dll(非.pyd)。
步骤示例
安装Nuitka
pip install nuitka编写带导出标记的Python模块
修改test.py,添加__nuitka_export__标记指定要导出的函数:def add(a: int, b: int) -> int: return a + b def greet(name: str) -> str: return f"Hello, {name}!" # 标记需要导出的函数 __nuitka_export__ = {"add": add, "greet": greet}生成.dll
执行以下命令:python -m nuitka --module test.py --windows-disable-console执行完成后会生成
test.dll,这是标准的Windows动态链接库,可被其他编程语言(如C/C#/VB)调用。
额外优化
- 若需要生成不依赖系统Python环境的独立.dll,可添加
--standalone参数,Nuitka会将依赖的Python运行时打包到同目录:python -m nuitka --module test.py --standalone --windows-disable-console - 若要静态链接Python(需预先编译Python静态库),可使用
--static-libpython=yes参数。
注意事项
- 方案一中,目标机器需安装对应版本的Python,或你需将Python的
python311.dll等依赖文件与生成的.dll一起分发。 - 导出函数的调用约定(如
__cdecl/__stdcall)需与调用方匹配,避免出现调用错误。
内容的提问来源于stack exchange,提问作者Vinay
相关产品推荐
相关产品推荐

