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

Python使用ctypes.CDLL调用DLL中libc函数时出现访问冲突问题

问题:加载自定义DLL调用libc函数触发访问违例

在Windows 11 64位系统下,使用Visual Studio 2022(或Cygwin-GCC、MinGW-GCC)编译自定义DLL,用Python 3.9.7的ctypes.CDLL加载后,DLL可正常加载,但调用malloc、strncpy等libc函数时触发访问违例错误。

最小复现代码

DLL代码(dllmain.cpp)

// dllmain.cpp : Definiert den Einstiegspunkt für die DLL-Anwendung.
#include "pch.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

#define DLLEXPORT extern "C" __declspec(dllexport)

#include<stdlib.h>
DLLEXPORT int exampl(void) {
    char* ex = (char*) malloc(100 * sizeof(char));
    return(42);
}

Python脚本(example.py)

import ctypes

lib = ctypes.CDLL("example.dll", winmode=1)
print(lib.exampl())

报错信息

python.exe .\example.py
Traceback (most recent call last):
  File "*<some path>*\example.py", line 4, in <module>
    print(lib.exampl())
OSError: exception: access violation writing 0x0000000000002A3C

问题原因与解决方案

核心原因

问题出在C运行时库(CRT)的兼容性上:

  • Python在Windows下默认使用微软的Visual C++ Runtime(UCRT),如果你的DLL使用静态链接CRT(如VS的/MT选项)或MinGW/Cygwin自带的CRT,会导致DLL和Python使用独立的堆空间。malloc等内存分配函数依赖CRT的堆管理,跨CRT堆操作会直接触发访问违例。

具体解决步骤

  1. Visual Studio编译设置

    • 打开项目属性,进入「C/C++ → 代码生成」,将「运行库」设置为多线程DLL (/MD)(Debug版用/MDd),确保DLL动态链接系统UCRT,和Python共享同一堆空间。
  2. MinGW/Cygwin编译设置

    • 编译时添加-msvcrt选项,强制链接系统的MSVC CRT,而不是MinGW自带的libgcc。例如:
      g++ -shared -o example.dll dllmain.cpp -msvcrt
      
  3. 验证位数一致性

    • 确保编译的DLL是64位版本,和Python的位数完全匹配(Python 3.9.7 64位对应64位DLL)。

内容的提问来源于stack exchange,提问作者broesel09-90

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 21:52:48