【问题标题】:Why do no Python DLLs built with MSVC load with mod_wsgi?为什么使用 MSVC 构建的 Python DLL 不使用 mod_wsgi 加载?
【发布时间】:2011-04-12 00:01:42
【问题描述】:

我最近从 Python 2.5 更新到 2.7(我在遇到麻烦时尝试了 2.6),虽然在命令行或 Django 运行服务器中一切正常,但 mod_wsgi 无法加载任何包含使用 MSVC 构建的 DLL (pyd) 的模块。

例如,如果我构建自己的 pycrypto 或 lxml 版本,那么我只会从 mod_wsgi 收到以下错误:

ImportError at /
DLL load failed: The specified module could not be found.

即使是官方的 PIL 二进制文件也无法在 mod_wsgi 中导入 _imaging C 模块,但这可能是另一个问题。

但是,如果我使用像 http://www.voidspace.org.uk/python/modules.shtml#pycrypto 这样的地方使用 MinGW 构建的 pycrypto 版本,那么即使在 mod_wsgi 中它也可以正常导入。我觉得这个解决方案并不令人满意,因为我更新 Python 的全部原因是为了避免需要寻找预构建的二进制文件,而且我无法自己构建它们,因为 MinGW 对我来说超过 50% 的时间都失败了。

编辑2: 我在 Python27/Lib/distutils/msvc9compiler.py 第 680-705 行注意到了这一点:

try:
    # Remove references to the Visual C runtime, so they will
    # fall through to the Visual C dependency of Python.exe.
    # This way, when installed for a restricted user (e.g.
    # runtimes are not in WinSxS folder, but in Python's own
    # folder), the runtimes do not need to be in every folder
    # with .pyd's.
    manifest_f = open(manifest_file)
    try:
        manifest_buf = manifest_f.read()
    finally:
        manifest_f.close()
    pattern = re.compile(
        r"""<assemblyIdentity.*?name=("|')Microsoft\."""\
        r"""VC\d{2}\.CRT("|').*?(/>|</assemblyIdentity>)""",
        re.DOTALL)
    manifest_buf = re.sub(pattern, "", manifest_buf)
    pattern = "<dependentAssembly>\s*</dependentAssembly>"
    manifest_buf = re.sub(pattern, "", manifest_buf)
    manifest_f = open(manifest_file, 'w')
    try:
        manifest_f.write(manifest_buf)
    finally:
        manifest_f.close()
except IOError:
    pass

这可能解释了为什么一切都可以在命令行中运行,而不是在 mod_wsgi 中。评论所有这些似乎可以解决问题,但感觉不是正确的解决方法。现在的问题是把 msvcr90.dll 放在哪里以便 Apache 可以使用它?我注意到 Apache 的 bin 文件夹包含 msvcr70.dll 和 msvcr80.dll,但将 90 放在那里不起作用。

【问题讨论】:

  • 在 IIS 下使用 pyodbc 跳过删除清单也对我有用

标签: python visual-c++ mod-wsgi


【解决方案1】:

我在使用 zmq 时遇到了这个错误。解决方案是在 libzmq.pyd 文件中包含 python27.dll 清单(它很可能适用于其他 pyd/dll)。确保使用全部 64 位或全部 32 位。

"C:\Program Files (x86)\Windows Kits\8.0\bin\x64\mt.exe" -inputresource:C:\windows\system32\python27.dll;#2 -outputresource:libzmq.pyd;#2

https://code.google.com/p/pyodbc/issues/detail?id=214

【讨论】:

    【解决方案2】:

    我遇到了类似的问题,最终找到了解决方案 here:使用来自 http://www.apachelounge.com/download/ 的服务器下载/更新您的 apache 服务器。

    【讨论】:

      【解决方案3】:

      虽然我对 mod_wsgi 一无所知,但我敢猜测最可能的原因是缺少运行时依赖项。您可能希望使用 MSVC 附带的 Dependency Walker 检查您的 MSVC 构建(例如,在 MSVC 2005 中,它位于 \Common7\Tools\Bin\Depends.Exe)。它将显示二进制文件需要哪些 DLL。

      作为另一种解决方法,应该可以使用静态链接运行时构建模块(请参阅项目属性 -> C/C++ -> 代码生成 -> 运行时 - 选择“多线程”(而不是“多线程 DLL”);或,如果从命令行构建,请确保使用 /MT 而不是 /MD)。但是,如果依赖于运行时的事物(例如 FILE* 对象)跨越模块边界,则可能会出现问题。

      UPD 如果你安装了正确的 VC redist,原因可能是 SxS 配置有问题(即 .pyd 本身的清单错误或丢失,或与加载 .pyd 的应用程序的清单)。您可以使用sxstrace 实用程序查看到底发生了什么。见Diagnosing SideBySide failures

      另外,您是否尝试过运行时的静态链接?或者,更好的是,检查主机进程的要求。

      【讨论】:

      • 他们缺少 MSVCR90.DLL(以及 GPSVC 和 IESHIMS)。我将 MSVCR90.DLL 与 AES.pyd 和 Dependency Walker 一起放置,但 Apache 给出了运行时错误。我确实有 VC redist,MSVCR90.dll 位于 C:\Windows\winsxs 下的各个文件夹中。有什么想法吗?
      • 我编辑了原始问题以显示 AES.pyd 的实际构建方式。它会作为评论被破坏。
      • @Kyle MacFarlane - 我已经编辑了我的答案以响应 cmets
      • 我再次编辑了问题。关于它目前的状况有什么想法吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-25
      • 2011-04-01
      • 2018-10-26
      • 2012-10-26
      • 2010-11-10
      • 1970-01-01
      相关资源
      最近更新 更多