2010-09-14 1 views
6

Недавно я обновился от Python 2.5 до 2.7 (я пробовал 2,6 во время моих проблем), и, хотя все работает отлично от командной строки или на сервере Django, mod_wsgi не может загрузить какой-либо модуль, содержащий DLL (pyd), созданный с помощью MSVC.Почему нет DLL-библиотек Python, построенных с загрузкой MSVC с помощью mod_wsgi?

Например, если я строю свои собственные версии PyCrypto или LXML тогда я получаю следующую ошибку только из mod_wsgi:

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

Даже официальные PIL бинарники не импортировать модуль _imaging C в mod_wsgi но это может быть другой проблемой.

Однако, если я использую версию pycrypto, построенную с MinGW от где-то вроде http://www.voidspace.org.uk/python/modules.shtml#pycrypto, тогда она будет импортировать даже в mod_wsgi. Я не нашел это решение удовлетворительным, хотя, поскольку вся причина, по которой я обновлял Python, заключалась в том, чтобы избежать необходимости искать готовые двоичные файлы, и я не могу их самостоятельно создать, потому что MinGW не работает> 50% времени для меня.

EDIT2: Я заметил это в 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 мог его использовать? Я замечаю, что папка bin в Apache содержит msvcr70.dll и msvcr80.dll, но включение 90 в нее не работает.

+1

Пропустив удалить манифест работал для меня под IIS тоже с pyodbc – lambacck

ответ

1

Хотя я ничего не знаю о mod_wsgi, я смею предположить, что наиболее вероятной причиной является отсутствие зависимостей во время выполнения. Вы можете проверить свою MSVC-сборку с помощью Dependency Walker, который поставляется с MSVC (например, в MSVC 2005, он находится в \ Common7 \ Tools \ Bin \ Depends.Exe). Он покажет вам, какие библиотеки DLL необходимы для двоичного кода.

В качестве другого обходного пути должно быть возможно построить ваши модули со статически связанной средой выполнения (см. «Свойства проекта» -> C/C++ -> Генерация кода -> Время выполнения - выберите «Многопоточность» (не «Многопоточная библиотека DLL»); или, если вы строите из командной строки, убедитесь, что вместоиспользуется /MT). Однако могут возникнуть проблемы, если зависящие от времени вещи (например, объекты FILE *) пересекают границу модуля.

UPD Если установлен правильно VC Redist, причина может быть проблемой с конфигурацией SxS (т.е. манифест .pyd сам является неправильным или отсутствуют, или конфликты с манифестом приложения, которое загружает .pyd). Вы можете использовать утилиту sxstrace, чтобы узнать, что именно происходит. См. Diagnosing SideBySide failures.

Кроме того, вы пробовали статическую компоновку среды выполнения? Или, еще лучше, проверьте, каковы требования вашего хост-процесса.

+0

Они не хватает msvcr90.dll (и GPSVC и IESHIMS). Я поместил MSVCR90.DLL вместе с проходами AES.pyd и Dependency Walker, но Apache дает ошибку времени выполнения. У меня есть VC redist, а файл MSVCR90.dll находится в разных папках под C: \ Windows \ winsxs. Есть идеи? –

+0

Я отредактировал оригинальный вопрос, чтобы показать, как фактически создан AES.pyd. Это было бы искалечено как комментарий. –

+0

@Kyle MacFarlane - я отредактировал свой ответ в ответ на комментарии – atzz

0

Я получал эту ошибку с zmq. Решение состояло в том, чтобы включить манифест python27.dll в файл libzmq.pyd (и он, скорее всего, будет работать для других 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