为什么没有使用mod_wsgi加载MSVC构建的Python DLL?

Kyl*_*ane 6 python mod-wsgi visual-c++

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

例如,如果我构建自己的pycrypto或lxml版本,那么我将仅从mod_wsgi获得以下错误:

ImportError at /
DLL load failed: The specified module could not be found.
Run Code Online (Sandbox Code Playgroud)

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

但是,如果我使用从http://www.voidspace.org.uk/python/modules.shtml#pycrypto这样的地方使用MinGW构建的pycrypto版本,那么即使在mod_wsgi中它也会导入很好.我发现这个解决方案并不令人满意,因为我更新Python的全部原因是为了避免需要搜索预构建的二进制文件而且我不能自己构建它们因为MinGW失败了> 50%的时间对我而言.

EDIT2:我在第680-705行的Python27/Lib/distutils/msvc9compiler.py中注意到了这一点:

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
Run Code Online (Sandbox Code Playgroud)

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

atz*_*tzz 1

虽然我对 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实用程序来查看到底发生了什么。请参阅诊断并排故障

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