2010-09-14 4 views
6

J'ai récemment mis à jour de Python 2.5 à 2.7 (j'ai essayé 2.6 pendant mes tracas) et bien que tout fonctionne correctement depuis la ligne de commande ou dans le serveur Django, mod_wsgi ne peut charger aucun module contenant des DLLs.Pourquoi les DLL Python créées avec MSVC ne sont-elles pas chargées avec mod_wsgi?

Par exemple, si je construis mes propres versions de pycrypto ou lxml alors je vais obtenir l'erreur suivante seulement de mod_wsgi:

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

Même les binaires LIP officiels ne parviennent pas à importer le module _imaging C dans mod_wsgi mais cela peut être un autre problème.

Cependant, si j'utilise une version de pycrypto construite avec MinGW à partir de quelque chose comme http://www.voidspace.org.uk/python/modules.shtml#pycrypto alors il importera bien même dans mod_wsgi. Je ne trouve pas cette solution satisfaisante bien que la raison pour laquelle j'ai mis à jour Python était d'éviter de chercher des binaires précompilés et je ne peux pas les construire moi-même car MinGW échoue> 50% du temps pour moi.

EDIT2: Je l'ai remarqué dans Python27/Lib/distutils/msvc9compiler.py sur les lignes 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 

Cela explique probablement pourquoi tout fonctionne à partir de la ligne de commande, mais pas dans mod_wsgi. Commenter tout cela semble résoudre le problème, mais ne se sent pas comme le correctif approprié. La question est maintenant de savoir où mettre msvcr90.dll afin qu'Apache puisse l'utiliser? Je remarque que le dossier de bin d'Apache contient msvcr70.dll et msvcr80.dll mais en mettant 90 dedans là ne fonctionne pas.

+1

Skipping supprimer manifeste a fonctionné pour moi aussi sous IIS avec pyodbc – lambacck

Répondre

1

Bien que je ne sache rien de mod_wsgi, j'ose deviner que la raison la plus probable est l'absence de dépendances à l'exécution. Vous souhaiterez peut-être inspecter votre build MSVC avec Dependency Walker fourni avec MSVC (par exemple, dans MSVC 2005, il se trouve dans \ Common7 \ Tools \ Bin \ Depends.Exe). Il vous montrera quelles DLL sont requises par un binaire. Comme autre solution de contournement, il devrait être possible de construire vos modules avec runtime lié statiquement (voir Propriétés du projet -> C/C++ -> Génération de code -> Runtime - choisissez "Multithread" (pas "Multithreaded DLL"); ou, si vous construisez à partir de la ligne de commande, assurez-vous que /MT est utilisé au lieu de /MD). Cependant, il peut y avoir des problèmes si des éléments dépendants de l'exécution (par exemple, des objets FILE *) traversent la limite du module.

UPD Si vous avez installé correctement VC Redist, la raison peut être un problème avec la configuration SxS (c.-à-manifeste d'elle-même .pyd est incorrecte ou manquante, ou en conflit avec manifeste de l'application qui charge le .pyd). Vous pouvez utiliser l'utilitaire sxstrace pour voir ce qui se passe exactement. Voir Diagnosing SideBySide failures.

Aussi, avez-vous essayé la liaison statique de l'exécution? Ou, mieux encore, vérifiez quelles sont les exigences de votre processus hôte.

+0

Ils ratent msvcr90.dll (et GPSVC et IESHIMS). Je mets MSVCR90.DLL aux côtés des passes AES.pyd et Dependency Walker mais Apache donne une erreur d'exécution. J'ai le redist de VC et MSVCR90.dll est dans divers dossiers sous C: \ Windows \ winsxs. Des idées? –

+0

J'ai édité la question originale pour montrer comment AES.pyd est réellement construit. Il aurait été mutilé comme un commentaire. –

+0

@Kyle MacFarlane - J'ai édité ma réponse en réponse aux commentaires – atzz

0

Je recevais cette erreur avec zmq. La solution consistait à inclure le manifeste python27.dll dans le fichier libzmq.pyd (et cela fonctionnera très probablement pour d'autres pyd/dll). Assurez-vous d'utiliser tous les 64 bits ou tous les 32 bits.

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

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

Questions connexes