2010-09-14 6 views
6

Niedawno zaktualizowałem z Pythona 2.5 do 2.7 (próbowałem 2.6 podczas moich kłopotów) i podczas gdy wszystko działa poprawnie z linii poleceń lub w runserver Django, mod_wsgi nie może załadować żadnego modułu, który zawiera DLL (pyd) zbudowany z MSVC.Dlaczego nie utworzono bibliotek DLL Pythona z obciążeniem MSVC za pomocą mod_wsgi?

Na przykład, jeśli budować własne wersje pycrypto lub lxml potem dostanie się następujący błąd tylko z mod_wsgi:

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

Nawet oficjalne binaria PIL nie uda się zaimportować moduł _imaging C w mod_wsgi ale to może być kolejny problem.

Jednakże, jeśli użyję wersji pycrypto zbudowanej z MinGW z innego miejsca niż http://www.voidspace.org.uk/python/modules.shtml#pycrypto, to zaimportuje ona drobne nawet w mod_wsgi. Nie uważam tego rozwiązania za satysfakcjonujące, ponieważ cały powód, dla którego aktualizowałem Pythona, polegał na tym, aby uniknąć konieczności szukania wstępnie skompilowanych plików binarnych i nie mogę ich samemu zbudować, ponieważ MinGW zawodzi> 50% czasu dla mnie.

EDIT2: Zauważyłem to w Python27/lib/distutils/msvc9compiler.py na liniach 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 

To prawdopodobnie wyjaśnia, dlaczego wszystko działa z wiersza polecenia, ale nie w mod_wsgi. Komentowanie tego wszystkiego wydaje się naprawić problem, ale nie wydaje się, aby poprawne rozwiązanie. Teraz pytanie, gdzie umieścić msvcr90.dll, aby Apache mógł z niego korzystać? Zauważyłem, że folder bin Apache zawiera msvcr70.dll i msvcr80.dll, ale umieszczenie tam 90 nie działa.

+1

Pomijanie usunąć manifestu pracował dla mnie zbyt pod IIS z pyodbc – lambacck

Odpowiedz

1

Chociaż nie wiem nic o mod_wsgi, odważę się domyślać, że najbardziej prawdopodobnym powodem jest brak zależności środowiska wykonawczego. Możesz sprawdzić swoją kompilację MSVC za pomocą Dependency Walker, która jest dostarczana z MSVC (np. W MSVC 2005, znajduje się w katalogu \ Common7 \ Tools \ Bin \ Depends.Exe). Pokaże ci, które pliki DLL są wymagane przez plik binarny.

W innym obejściu, powinno być możliwe budowanie modułów z statycznie połączonym środowiskiem wykonawczym (zobacz Właściwości projektu -> C/C++ -> Generowanie kodu -> Środowisko uruchomieniowe - wybierz "Wielowątkowe" (nie "Wielowątkowa biblioteka DLL"); lub, jeśli budujesz z wiersza poleceń, upewnij się, że zamiast /MD jest używane /MT). Mogą jednak wystąpić problemy, jeśli obiekty zależne od środowiska wykonawczego (na przykład obiekty FILE *) przekraczają granicę modułu.

UPD Jeśli masz zainstalowane poprawne VC redist, powodem może być problem z konfiguracją SxS (czyli manifest .pyd sama jest błędne lub brakujące lub konfliktów z manifestu aplikacji, która ładuje .pyd). Możesz użyć narzędzia sxstrace, aby zobaczyć, co dokładnie się dzieje. Zobacz Diagnosing SideBySide failures.

Czy próbowałeś statycznego łączenia środowiska wykonawczego? Lub, jeszcze lepiej, sprawdź, jakie są wymagania twojego hosta.

+0

Oni brakuje Msvcr90.dll (i GPSVC i IESHIMS). Wstawiłem MSVCR90.DLL wraz z AES.pyd i Dependency Walker przechodzi, ale Apache daje błąd runtime. Mam redystę VC i MSVCR90.dll jest w różnych folderach w C: \ Windows \ winsxs. Jakieś pomysły? –

+0

Edytowałem oryginalne pytanie, aby pokazać, jak faktycznie zbudowano AES.pyd. Zostałoby to zniekształcone jako komentarz. –

+0

@Kyle MacFarlane - Edytowałem swoją odpowiedź w odpowiedzi na komentarze – atzz

0

Otrzymałem ten błąd za pomocą zmq. Rozwiązaniem było włączenie manifestu python27.dll do pliku libzmq.pyd (i najprawdopodobniej będzie działać dla innych plików pyd/dll). Upewnij się, że używasz wszystkich 64-bitowych lub wszystkich 32-bitowych.

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

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