You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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运行时,路径中已包含相关库,因此无问题。

解决办法

  1. 静态链接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文件。

  2. 确保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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:26:26