Dav*_*vid 8 c++ python dll manifest visual-studio
我包含python.h
在我的Visual C++ DLL文件项目中,该项目导致隐式链接python25.dll
.但是,我想加载一个特定的python25.dll
(计算机上可以存在几个),所以我创建了一个名为test.manifest的非常简单的清单文件:
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<file name="python25.dll" />
</assembly>
Run Code Online (Sandbox Code Playgroud)
我正在将它与Visual Studio生成的自动嵌入式清单文件合并,这要归功于:
Configuration Properties -> Manifest Tool -> Input and Output -> Additional Manifest Files
-->$(ProjectDir)\src\test.manifest
Run Code Online (Sandbox Code Playgroud)
python25.dll
现在加载了两次:清单请求的那个,以及Windows应该通过其搜索顺序找到的那个.
Process Explorer的Screendump http://dl.dropbox.com/u/3545118/python25_dll.png
为什么会发生这种情况?如何加载清单指向的DLL文件?
在与WinSxS和DLL重定向进行彻底的战斗之后,这是我对你的建议:
各种事情可能导致在Windows下加载DLL文件:
LoadLibrary
) - 加载程序使用正在运行的EXE文件的当前激活上下文.这很直观.A.exe
依赖于B.dll
依赖C.dll
(所有隐式链接),加载程序将使用B.dll
时加载的激活上下文C.dll
.IIRC,这意味着如果B DllMain
加载C.dll
,它可以使用B.dll
激活上下文 - 大多数时候它意味着系统范围的默认激活上下文.所以你从中得到了你的Python DLL %SystemRoot%
.CoCreateInstance
) - 这是令人讨厌的.非常微妙.事实证明,加载器可以使用COM(下)从注册表中查找DLL文件的完整路径HKCR\CLSID
.LoadLibrary
如果用户给它一个完整路径,则不会进行任何搜索,因此激活上下文不会影响DLL文件解析.这些可以与comClass
元素和朋友重定向,请参见[reference] [msdn_assembly_ref].bp kernel32!ActivateActCtx
.python25.dll
"或" 包含详细信息python25.dll
"(用于COM查找).双击条目实际上会显示堆栈跟踪(您需要先设置符号搜索路径,还要设置Microsoft的PDB服务器).这应该足以满足您的大部分需求.sxe ld python25
看看其他线程正在做什么(!findstack MyExeModuleName
或~*k
)导致DLL文件加载.而不是摆弄这个WinSxS的东西,尝试LoadLibraryW
使用Mhook或EasyHook挂钩.您可以使用自定义逻辑完全替换该调用.你可以在午餐前完成这项工作,再次找到生命的意义.
[msdn_assembly_ref]:装配清单
Dependency Walker通常是解决此类问题的最佳工具。我不太确定它处理清单的效果如何......
在这个混乱的混乱中,实际的进程可执行文件在哪里?
我想到了两种可能性:
您正在编写一个 Python 扩展 DLL 文件。因此,Python 进程正在加载您的 DLL 文件,并且它已经拥有自己的 python25.dll 依赖项。
加载 DLL 文件的 EXE 文件是使用 DLL 文件项目提供的头文件和库构建的。所以它#pragma comment(lib,"python25.lib")
从你的头文件继承,结果是加载 DLL 文件本身。
第二种情况的问题是,我希望 EXE 文件和 DLL 文件位于同一文件夹中,以防 EXE 文件隐式加载 DLL 文件。在这种情况下,EXE 文件、DLL 文件和 python25.dll 都已位于同一文件夹中。那么为什么会加载 system32 版本呢?隐式加载的 DLL 文件的搜索顺序始终位于应用程序 EXE 文件的文件夹中。
因此,您的查询中隐含的实际有趣的问题是:system32 python26.dll 是如何加载的?