Python加载C++共享库时使用new关键字触发DLL加载失败问题
问题:C++动态库使用
new时Python ctypes加载失败 环境:Windows 11、Python 3.1
现象:
- 自行编译的C++共享库
libkv_module_shared.dll,代码不含new int;时,Python通过ctypes可正常加载调用; - 加入
new int;语句后,触发FileNotFoundError,提示无法找到模块或其依赖; - 用
malloc()替代new则运行正常; - 尝试过WinDLL、CDLL、调整路径配置、修改winmode参数,均未解决问题。
C++代码
int a = 7; extern "C" { __declspec(dllexport) size_t setup() { //new int; works unless commented in return ++a; } }
Python代码
from flask import Flask, jsonify, request import os import ctypes #DLL_REL_PATH = './cmake-build-debug/' DLL = 'libkv_module_shared.dll' DLL_FULL_PATH = "C:/Users/editn/CLionProjects/kv_module_shared/cmake-build-debug/" os.add_dll_directory(DLL_FULL_PATH) os.environ['PATH'] += DLL_FULL_PATH clib = ctypes.WinDLL(DLL) print("Using clib={:}".format(clib)) clib.setup.argtypes = () clib.setup.restype = ctypes.c_ssize_t print(clib.setup())
原因及解决办法
原因
new是C标准库操作符,依赖C运行时库(如MSVCRT、UCRT)。编译动态库时若默认使用动态链接C运行时,生成的DLL会依赖VC Redistributable包中的对应库文件。这些依赖库不在Python进程的搜索路径中时,就会触发加载失败。而malloc()属于C标准库函数,Python本身依赖C运行时,路径中已包含相关库,因此无问题。
解决办法
静态链接C++运行时库:
若使用CMake编译(从cmake-build-debug目录可判断),修改CMakeLists.txt,添加静态链接编译选项:set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")重新编译后,DLL会将C运行时库打包进自身,不再依赖外部VC Redistributable文件。
确保C++运行时库在搜索路径中:
- 安装对应版本的VC++ Redistributable包(根据编译所用Visual Studio版本选择,如VS2022对应最新版本);
- 将运行时库所在路径(例如
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Redist\MSVC\14.38.33130\x64\Microsoft.VC143.CRT)添加到系统PATH,或在Python代码中通过os.add_dll_directory添加该路径。
内容的提问来源于stack exchange,提问作者yuval Nir
相关产品推荐
相关产品推荐

