VisualStudio安装
![](/icons/6898chengxu.gif)
会把VisualStudio
![](/icons/6898de.gif)
共享库放在
![](/icons/6898yi.gif)
个称为\"并列缓存Cache(side-by-sidecache)\"
![](/icons/6898de.gif)
地方
![](/icons/6898dou.gif)
那怎样才能有效地利用它呢?
在文章开头
![](/icons/6898dou.gif)
先看
![](/icons/6898yi.gif)
个举例
![](/icons/6898dou2.gif)
在命令行中
![](/icons/6898dou.gif)
创建
![](/icons/6898yi.gif)
个源文件
![](/icons/6898dou.gif)
输入例1中
![](/icons/6898de.gif)
代码
![](/icons/6898dou2.gif)
(虽然此处使用
![](/icons/6898de.gif)
是C
![](/icons/6898jiajia.gif)
/CLI语法
![](/icons/6898dou.gif)
但不管你是用C
![](/icons/6898jiajia.gif)
/CLI、托管C
![](/icons/6898jiajia.gif)
、或本地C
![](/icons/6898jiajia.gif)
![](/icons/6898dou.gif)
都不影响要讲解
![](/icons/6898de.gif)
主题
![](/icons/6898dou2.gif)
)
例1:lib.cpp
using
![](/icons/6898namespace.gif)
![](/icons/6898System.gif)
;
publicref
![](/icons/6898class.gif)
Test
{
public:
voidCallMe
{
Console::WriteLine(\"calledme\");
}
};
将其编译为
![](/icons/6898yi.gif)
个托管库
![](/icons/6898chengxu.gif)
集:
cl/clr/LDlib.cpp
在此要多留意
![](/icons/6898dou.gif)
我们是使用了混合模式(/clr)来编译此代码
![](/icons/6898dou.gif)
当然了
![](/icons/6898dou.gif)
如果适当修改
![](/icons/6898dou.gif)
也能以旧式托管C
![](/icons/6898jiajia.gif)
语法(/clr:oldsyntax)来编译
下
![](/icons/6898yi.gif)
步
![](/icons/6898dou.gif)
创建
![](/icons/6898yi.gif)
个
![](/icons/6898diaoyong.gif)
此库
![](/icons/6898de.gif)
C#
![](/icons/6898chengxu.gif)
(例2)
![](/icons/6898dou.gif)
当然也可以使用VisualBasic.NET
![](/icons/6898dou.gif)
不过C#更好
![](/icons/6898yi.gif)
点
![](/icons/6898dou2.gif)
再和库
![](/icons/6898yi.gif)
起编译:
例2:
using
![](/icons/6898System.gif)
;
![](/icons/6898class.gif)
App
{
![](/icons/6898static.gif)
voidMain
{
Testtest=
![](/icons/6898new.gif)
Test
![](/icons/6898kh.gif)
;
test.CallMe
![](/icons/6898kh.gif)
;
}
}
cscapp.cs/r:lib.dll
运行此
![](/icons/6898chengxu.gif)
![](/icons/6898dou.gif)
会抛出
![](/icons/6898yi.gif)
个异常:
UnhandledException:
![](/icons/6898System.gif)
.IO.FileNotFoundException:
Thespec
![](/icons/6898if.gif)
iedmodulecouldnotbefound.
(ExceptionfromHRESULT:0x8007007E)
atApp.Main
如何会这样呢?打开
![](/icons/6898chengxu.gif)
所在
![](/icons/6898de.gif)
目录
![](/icons/6898dou.gif)
库也在那啊
![](/icons/6898dou2.gif)
HRESULT
![](/icons/6898de.gif)
高位字为0x8007
![](/icons/6898dou.gif)
其代表FACILITY_WIN32
![](/icons/6898dou.gif)
也就是说
![](/icons/6898dou.gif)
这是
![](/icons/6898yi.gif)
个Win32
![](/icons/6898cuowu.gif)
;低位字以十进制表示为126
![](/icons/6898dou.gif)
在winerror.h中列明其代表ERROR_MOD_NOT_FOUND
![](/icons/6898dou2.gif)
如果LoadLibrary不能查找到某个模块
![](/icons/6898dou.gif)
才会返回这个
![](/icons/6898cuowu.gif)
结果
![](/icons/6898dou.gif)
因此
![](/icons/6898dou.gif)
现在非常清楚了
![](/icons/6898dou.gif)
这个
![](/icons/6898cuowu.gif)
表示不能查找到
![](/icons/6898yi.gif)
个非托管
![](/icons/6898de.gif)
DLL
为找出库所使用
![](/icons/6898de.gif)
模块列表
![](/icons/6898dou.gif)
可在ILDASM中加载它
![](/icons/6898dou.gif)
并查看MANIFEST
![](/icons/6898dou2.gif)
如果库是通过平台
![](/icons/6898diaoyong.gif)
加载DLL
![](/icons/6898de.gif)
![](/icons/6898dou.gif)
那这些DLL会作为.module条目列出
![](/icons/6898dou.gif)
然而
![](/icons/6898dou.gif)
对这个库来说
![](/icons/6898dou.gif)
你将会发现
![](/icons/6898dou.gif)
它只用到了托管
![](/icons/6898chengxu.gif)
集mscorlib和Microsoft.VisualC
![](/icons/6898dou.gif)
两者都在.NET全局
![](/icons/6898chengxu.gif)
集缓存Cache(GAC)中
![](/icons/6898dou2.gif)
另有
![](/icons/6898yi.gif)
种可能性
![](/icons/6898dou.gif)
在
![](/icons/6898chengxu.gif)
集中
![](/icons/6898dou.gif)
还存在着非托管代码
![](/icons/6898dou.gif)
由它
![](/icons/6898diaoyong.gif)
了非托管库(例如
![](/icons/6898dou.gif)
那些使用托管C
![](/icons/6898jiajia.gif)
ItJustWorks
![](/icons/6898de.gif)
代码)
为调查清楚
![](/icons/6898dou.gif)
从ILDASM
![](/icons/6898de.gif)
View菜单中选项Headers
![](/icons/6898dou.gif)
这将会列出库中
![](/icons/6898de.gif)
PE文件头
![](/icons/6898dou2.gif)
向下滚动直至找到导入表(IAT)
![](/icons/6898dou.gif)
会得到
![](/icons/6898yi.gif)
份所有从非托管库引入
![](/icons/6898de.gif)
思路方法列表
![](/icons/6898dou2.gif)
![](/icons/6898yinwei.gif)
库是以混合模式编译
![](/icons/6898de.gif)
![](/icons/6898dou.gif)
因此库用到了C运行时库(CRT)
![](/icons/6898dou.gif)
从导入表中也确认了这点--它列出了msvcr80.dll及msvcm80.dll
![](/icons/6898dou.gif)
前者是CRT
![](/icons/6898de.gif)
DLL多线程版本
![](/icons/6898dou.gif)
后者是
![](/icons/6898yi.gif)
个包含了
![](/icons/6898yi.gif)
些CRT托管版本
![](/icons/6898de.gif)
混合模式库
![](/icons/6898dou2.gif)
这下非常清楚了
![](/icons/6898dou.gif)
![](/icons/6898cuowu.gif)
产生
![](/icons/6898de.gif)
原因是找不到这两个库、或其
![](/icons/6898yi.gif)
最后
![](/icons/6898dou.gif)
查看%systemroot%\\system32目录下是否有这些库--但它们不会在那
![](/icons/6898de.gif)
![](/icons/6898dou.gif)
此时
![](/icons/6898dou.gif)
你可能会指责VisualStudio安装
![](/icons/6898chengxu.gif)
没有把最新版本
![](/icons/6898de.gif)
CRT安装在自己
![](/icons/6898de.gif)
电脑上
![](/icons/6898dou.gif)
但实际上
![](/icons/6898dou.gif)
安装
![](/icons/6898chengxu.gif)
已经安装了这些CRT库--只是不在你原先期待
![](/icons/6898de.gif)
地方
并列缓存Cache
VisualStudio安装
![](/icons/6898chengxu.gif)
会把VisualStudio
![](/icons/6898de.gif)
共享库放在
![](/icons/6898yi.gif)
个称为\"并列缓存Cache(side-by-sidecache)\"
![](/icons/6898de.gif)
地方
![](/icons/6898dou.gif)
目录位于%systemroot%\\WinSxS
![](/icons/6898dou.gif)
且只有SYSTEM及Administrators组成员有写访问权限
![](/icons/6898dou.gif)
其他用户只有读取和运行权限
![](/icons/6898dou2.gif)
并列缓存Cache中包含了\"
![](/icons/6898chengxu.gif)
集\"--不是托管
![](/icons/6898chengxu.gif)
集
![](/icons/6898dou.gif)
而是非托管
![](/icons/6898de.gif)
等价物
![](/icons/6898dou2.gif)
[Page]
在WinSxS目录下
![](/icons/6898dou.gif)
每个
![](/icons/6898chengxu.gif)
集都会有
![](/icons/6898yi.gif)
个目录
![](/icons/6898dou.gif)
另外
![](/icons/6898dou.gif)
还有两个目录分别是Man
![](/icons/6898if.gif)
ests和Policies
![](/icons/6898dou.gif)
其中包含了版本
![](/icons/6898de.gif)
相关信息
![](/icons/6898dou2.gif)
以下两个目录和CRT有关:
x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0de06acd
x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_f75eb16c
显而易见
![](/icons/6898dou.gif)
![](/icons/6898yi.gif)
个是发布版(ReleaseBuild)
![](/icons/6898dou.gif)
而另
![](/icons/6898yi.gif)
个是调试版(DebugBuild)
![](/icons/6898dou.gif)
但重点是
![](/icons/6898dou.gif)
版本号和
![](/icons/6898yi.gif)
个公有密钥权标也是目录名
![](/icons/6898de.gif)
![](/icons/6898yi.gif)
部分
![](/icons/6898dou2.gif)
如果你查看前
![](/icons/6898yi.gif)
个目录
![](/icons/6898de.gif)
内容
![](/icons/6898dou.gif)
可看到有msvcm80.dll、msvcp80.dll、及msvcr80.dll
![](/icons/6898dou.gif)
它们是被称为\"Microsoft.VC80.CRT\"非托管
![](/icons/6898chengxu.gif)
集8.0.50727.42版本
![](/icons/6898de.gif)
内容
![](/icons/6898dou2.gif)
![](/icons/6898yi.gif)
个非托管
![](/icons/6898chengxu.gif)
集可包含
![](/icons/6898yi.gif)
个或多个文件
![](/icons/6898dou.gif)
而这些文件也可为包含本地代码或COM对象
![](/icons/6898de.gif)
DLL
![](/icons/6898dou2.gif)
![](/icons/6898yi.gif)
个非托管
![](/icons/6898chengxu.gif)
集通常被作为
![](/icons/6898yi.gif)
个单独
![](/icons/6898de.gif)
单元部署
![](/icons/6898dou.gif)
且其中
![](/icons/6898de.gif)
所有文件由
![](/icons/6898yi.gif)
个被称为\"清单(man
![](/icons/6898if.gif)
est)\"
![](/icons/6898de.gif)
文件来描述
清单文件在Man
![](/icons/6898if.gif)
est目录中
![](/icons/6898dou.gif)
且和
![](/icons/6898chengxu.gif)
集同名
![](/icons/6898dou.gif)
但是后缀名为.man
![](/icons/6898if.gif)
est
![](/icons/6898dou2.gif)
这个文件列出了
![](/icons/6898chengxu.gif)
集中
![](/icons/6898de.gif)
所有文件;此外
![](/icons/6898dou.gif)
还有
![](/icons/6898yi.gif)
个文件
![](/icons/6898de.gif)
文件名也和
![](/icons/6898chengxu.gif)
集同名
![](/icons/6898dou.gif)
但是后缀名为.cat
![](/icons/6898dou.gif)
这是
![](/icons/6898yi.gif)
个已签名
![](/icons/6898de.gif)
安全编目文件
![](/icons/6898dou.gif)
其包含了
![](/icons/6898chengxu.gif)
集中文件
![](/icons/6898de.gif)
hash值
![](/icons/6898dou.gif)
正是
![](/icons/6898yinwei.gif)
它已签名
![](/icons/6898dou.gif)
所以可以防止被篡改
![](/icons/6898dou.gif)
且Windows也能利用这些hash值来检查
![](/icons/6898chengxu.gif)
集
![](/icons/6898de.gif)
任
![](/icons/6898yi.gif)
部分是否在部署后已被篡改
客户清单文件
![](/icons/6898yi.gif)
个客户文件(
![](/icons/6898chengxu.gif)
或库)能依赖于
![](/icons/6898chengxu.gif)
集中
![](/icons/6898de.gif)
某个文件来构建
![](/icons/6898dou.gif)
但客户文件只会依赖于
![](/icons/6898chengxu.gif)
集
![](/icons/6898de.gif)
某个特定版本来构建
![](/icons/6898dou.gif)
也只会加载所需
![](/icons/6898de.gif)
特定版本
![](/icons/6898dou2.gif)
为标出所需共享
![](/icons/6898chengxu.gif)
集
![](/icons/6898de.gif)
版本
![](/icons/6898dou.gif)
![](/icons/6898yi.gif)
个可执行文件(
![](/icons/6898chengxu.gif)
或库)也必须有
![](/icons/6898yi.gif)
个清单文件(man
![](/icons/6898if.gif)
est)
![](/icons/6898dou2.gif)
链接器在可执行文件生成时
![](/icons/6898dou.gif)
会为其创建
![](/icons/6898yi.gif)
个包含清单信息
![](/icons/6898de.gif)
文件
![](/icons/6898dou.gif)
因此
![](/icons/6898dou.gif)
如果回过头来看
![](/icons/6898yi.gif)
下前面生成
![](/icons/6898de.gif)
库
![](/icons/6898de.gif)
目录
![](/icons/6898dou.gif)
会找到
![](/icons/6898yi.gif)
个名为\"lib.dll.man
![](/icons/6898if.gif)
est\"
![](/icons/6898de.gif)
文件
![](/icons/6898dou.gif)
例3是其
![](/icons/6898de.gif)
内容
例3:
<?xmlversion=’1.0’encoding=’UTF-8’standalone=’yes’?>
<assemblyxmlns=’urn:schemas-microsoft-com:asm.v1’man
![](/icons/6898if.gif)
estVersion=’1.0’>
<dependency>
<dependentAssembly>
<assemblyIdentitytype=’win32’name=’Microsoft.VC80.CRT’
version=’8.0.50608.0’processorArchitecture=’x86’
publicKeyToken=’1fc8b3b9a1e18e3b’/>
</dependentAssembly>
</dependency>
</assembly>
正如大家所看见
![](/icons/6898de.gif)
![](/icons/6898dou.gif)
它介绍说明托管
![](/icons/6898chengxu.gif)
集lib.dll依赖于Microsoft.VC80.CRT共享并列
![](/icons/6898chengxu.gif)
集中
![](/icons/6898de.gif)
某些文件
![](/icons/6898dou2.gif)
尽管这个文件位于库lib.dll
![](/icons/6898de.gif)
同
![](/icons/6898yi.gif)
目录中
![](/icons/6898dou.gif)
但Windows明显不会用到它
![](/icons/6898dou.gif)
而这和MSDN中写明
![](/icons/6898de.gif)
有点背道而驰:
(MSDN):你可在应用
![](/icons/6898chengxu.gif)
2进制可执行头文件中包含应用
![](/icons/6898chengxu.gif)
清单文件……
![](/icons/6898dou.gif)
作为备选方案
![](/icons/6898dou.gif)
也可把
![](/icons/6898yi.gif)
个单独
![](/icons/6898de.gif)
清单文件放在应用
![](/icons/6898chengxu.gif)
可执行文件
![](/icons/6898de.gif)
同
![](/icons/6898yi.gif)
目录中
![](/icons/6898dou.gif)
会首先从文件系统中加载此清单文件
![](/icons/6898dou.gif)
并检查可执行文件
![](/icons/6898de.gif)
资源节
![](/icons/6898dou2.gif)
文件系统
![](/icons/6898de.gif)
版本具有优先权
然而
![](/icons/6898dou.gif)
完全不是这么回事
![](/icons/6898dou2.gif)
对库而言
![](/icons/6898dou.gif)
Windows会忽略清单文件
![](/icons/6898dou.gif)
尽管如此
![](/icons/6898dou.gif)
文档还是给出了怎样解决这个问题
![](/icons/6898de.gif)
![](/icons/6898yi.gif)
个线索
![](/icons/6898dou.gif)
清单文件
![](/icons/6898yi.gif)
定要以资源ID为2
![](/icons/6898de.gif)
非托管资源RT_MANIFEST形式绑定到可执行文件
![](/icons/6898dou2.gif)
[Page]
在此有两种思路方法:第
![](/icons/6898yi.gif)
种思路方法是创建
![](/icons/6898yi.gif)
个包含对清单文件引用
![](/icons/6898de.gif)
资源脚本文件:
#
![](/icons/6898include.gif)
<winuser.h>
2RT_MANIFESTlib.dll.man
![](/icons/6898if.gif)
est
它会在以后通过Windows资源编译器rc.exe编译为
![](/icons/6898yi.gif)
个资源
![](/icons/6898dou.gif)
并通过链接器限定为
![](/icons/6898yi.gif)
个非托管资源
![](/icons/6898dou2.gif)
这种思路方法
![](/icons/6898de.gif)
问题的处在于
![](/icons/6898dou.gif)
是链接器创建了这个清单文件
![](/icons/6898dou.gif)
因此必须运行两次链接器:
![](/icons/6898yi.gif)
次是为生成清单文件
![](/icons/6898dou.gif)
![](/icons/6898yi.gif)
次是把资源链接到最终生成文件
![](/icons/6898dou2.gif)
例4是
![](/icons/6898yi.gif)
个范例makefile
![](/icons/6898dou.gif)
演示了如何进行操作:
例4:
#The
![](/icons/6898main.gif)
target
all:app.exe
#AC#processthatdependsuponaManagedlibrary
app.exe:app.cslib.dll
cscapp.cs/r:lib.dll
#Thisisthesecondinvocationofthelinker,sotheobjectfileand
#man
![](/icons/6898if.gif)
estwillalreadyexist,sotheydonotneedtoberebuilt.
lib.dll:lib.cpplib.reslib.obj
link/DLL/man
![](/icons/6898if.gif)
est:no/machine:x86lib.reslib.obj
lib.res:lib.rc
rclib.rc
#Createatemporaryresourcescriptthatbindstheman
![](/icons/6898if.gif)
estfiletotheDLL
lib.rc:lib.dll.man
![](/icons/6898if.gif)
est
type<<$@
#
![](/icons/6898include.gif)
<winuser.h>
2RT_MANIFESTlib.dll.man
![](/icons/6898if.gif)
est
<<KEEP
#Createtheobjectfile,andinvokethelinkertocreatetheman
![](/icons/6898if.gif)
estfile
lib.dll.man
![](/icons/6898if.gif)
estlib.obj:lib.cpp
cl/LD/clrlib.cpp
另
![](/icons/6898yi.gif)
个思路方法是使用mt.exe未公开
![](/icons/6898de.gif)
隐藏选项把资源绑定到最终生成文件上
![](/icons/6898dou.gif)
这也是VisualStudio2005创建加载
![](/icons/6898de.gif)
C
![](/icons/6898jiajia.gif)
库(托管混合模式或非托管模式)时所使用
![](/icons/6898de.gif)
思路方法
![](/icons/6898dou2.gif)
两个隐藏选项分别为/man
![](/icons/6898if.gif)
est和/outputresource:前者用于指定清单文件名
![](/icons/6898dou.gif)
而后者用于指出将要修改
![](/icons/6898de.gif)
PE文件及清单资源
![](/icons/6898de.gif)
资源ID
![](/icons/6898dou2.gif)
![](/icons/6898yi.gif)
般而言
![](/icons/6898dou.gif)
对库来说
![](/icons/6898dou.gif)
资源ID应为2;对
![](/icons/6898chengxu.gif)
来说
![](/icons/6898dou.gif)
应为1
![](/icons/6898dou2.gif)
请看以下举例:
mt/man
![](/icons/6898if.gif)
estlib.dll.man
![](/icons/6898if.gif)
est
/outputresource:lib.dll;#2
注意此处
![](/icons/6898de.gif)
区别:/man
![](/icons/6898if.gif)
est选项后跟
![](/icons/6898de.gif)
参数是用空格分隔
![](/icons/6898de.gif)
;而/outputresource选项后跟
![](/icons/6898de.gif)
参数是用冒号分隔
![](/icons/6898de.gif)
![](/icons/6898dou2.gif)
明显看得出
![](/icons/6898dou.gif)
这两个选项是由区别
![](/icons/6898de.gif)
![](/icons/6898chengxu.gif)
员开发
![](/icons/6898de.gif)
![](/icons/6898yi.gif)
旦你把清单文章绑定到库
![](/icons/6898dou.gif)
Windows就可以判断需加载
![](/icons/6898chengxu.gif)
集
![](/icons/6898de.gif)
正确版本
![](/icons/6898dou2.gif)
如果在作出这些修改的后
![](/icons/6898dou.gif)
运行前面
![](/icons/6898de.gif)
C#
![](/icons/6898chengxu.gif)
![](/icons/6898dou.gif)
也会发现
![](/icons/6898chengxu.gif)
运行正常
如果你生成了
![](/icons/6898yi.gif)
个混合模式(/clr)或纯媒介语言模式(/clr:pure)
![](/icons/6898de.gif)
托管C
![](/icons/6898jiajia.gif)
![](/icons/6898chengxu.gif)
![](/icons/6898dou.gif)
来使用这个混合模式
![](/icons/6898de.gif)
库
![](/icons/6898dou.gif)
链接器也创建了
![](/icons/6898yi.gif)
个相应
![](/icons/6898de.gif)
![](/icons/6898chengxu.gif)
清单文件
![](/icons/6898dou.gif)
当此
![](/icons/6898chengxu.gif)
运行时
![](/icons/6898dou.gif)
Windows会查找资源ID为1
![](/icons/6898de.gif)
清单文件
![](/icons/6898dou.gif)
或查找名为man
![](/icons/6898if.gif)
est
![](/icons/6898de.gif)
相应文件
![](/icons/6898dou2.gif)
![](/icons/6898yinwei.gif)
混合模式或纯媒介语言模式
![](/icons/6898chengxu.gif)
都用到了CRT
![](/icons/6898dou.gif)
意味着将会在清单文件中提及CRT
![](/icons/6898chengxu.gif)
集
![](/icons/6898dou.gif)
所以
![](/icons/6898dou.gif)
在这个特例中
![](/icons/6898dou.gif)
库不需要清单文件
![](/icons/6898dou2.gif)
然而
![](/icons/6898dou.gif)
你不应该依赖这个机制
![](/icons/6898dou.gif)
![](/icons/6898yinwei.gif)
在本例中
![](/icons/6898dou.gif)
![](/icons/6898chengxu.gif)
使用同
![](/icons/6898yi.gif)
个非托管
![](/icons/6898chengxu.gif)
集作为库是
![](/icons/6898yi.gif)
个偶然情况
![](/icons/6898dou2.gif)
[Page]
版本重定向
回过头来再看
![](/icons/6898yi.gif)
下为库创建
![](/icons/6898de.gif)
清单文件
![](/icons/6898dou.gif)
注意
![](/icons/6898chengxu.gif)
集所需
![](/icons/6898de.gif)
版本号给定为8.0.50608.0
![](/icons/6898dou.gif)
再次提醒
![](/icons/6898dou.gif)
VisualStudio2005安装
![](/icons/6898de.gif)
![](/icons/6898chengxu.gif)
集是8.0.50727.42
![](/icons/6898dou.gif)
这个叫策略版本重定向
![](/icons/6898dou2.gif)
在并列缓存Cache
![](/icons/6898de.gif)
同级Policies目录中
![](/icons/6898dou.gif)
可找到下面这个文件夹:
x86_policy.8.0.Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_x-ww_77c24773
注意
![](/icons/6898dou.gif)
除了版本部分
![](/icons/6898dou.gif)
它有着
![](/icons/6898chengxu.gif)
集
![](/icons/6898de.gif)
全名
![](/icons/6898dou2.gif)
此文件夹中分别包含了
![](/icons/6898yi.gif)
个策略及安全编目文件
![](/icons/6898dou.gif)
文件名基于将要重定向至
![](/icons/6898de.gif)
版本号:
8.0.50727.42.policy
这是
![](/icons/6898yi.gif)
个文件(见例5)
![](/icons/6898dou2.gif)
这个策略文件是针对版本8.0.50727.42
![](/icons/6898de.gif)
![](/icons/6898dou.gif)
其也是VisualStudio安装
![](/icons/6898chengxu.gif)
所安装
![](/icons/6898de.gif)
版本
![](/icons/6898dou2.gif)
它在<bindingRedirect>中指明了所有将要被重定向至本版本
![](/icons/6898de.gif)
版本号
![](/icons/6898dou.gif)
例5中表明
![](/icons/6898dou.gif)
对版本号8.0.41204.256至8.0.50608.0
![](/icons/6898chengxu.gif)
集
![](/icons/6898de.gif)
所有请求
![](/icons/6898dou.gif)
都会被重定向至8.0.50727.42这个版本
![](/icons/6898dou2.gif)
和Fusion(混淆:.NET中
![](/icons/6898de.gif)
![](/icons/6898chengxu.gif)
集加载技术)区别
![](/icons/6898de.gif)
是
![](/icons/6898dou.gif)
对并列共享
![](/icons/6898chengxu.gif)
集
![](/icons/6898de.gif)
版本重定向只能是那些生成或修订
![](/icons/6898de.gif)
版本值的间
![](/icons/6898de.gif)
变化
![](/icons/6898dou.gif)
不能用于主、副版本值
![](/icons/6898de.gif)
变化
例5:
<?xmlversion=\"1.0\"encoding=\"UTF-8\"standalone=\"yes\"?>
<!--Copyright(r)1981-2001MicrosoftCorporation-->
<assemblyxmlns=\"urn:schemas-microsoft-com:asm.v1\"man
![](/icons/6898if.gif)
estVersion=\"1.0\">
<assemblyIdentitytype=\"win32-policy\"name=\"policy.8.0.Microsoft.VC80.CRT\"
version=\"8.0.50727.42\"processorArchitecture=\"x86\"
publicKeyToken=\"1fc8b3b9a1e18e3b\"/>
<dependency>
<dependentAssembly>
<assemblyIdentitytype=\"win32\"name=\"Microsoft.VC80.CRT\"
processorArchitecture=\"x86\"publicKeyToken=\"1fc8b3b9a1e18e3b\"/>
<bindingRedirectoldVersion=\"8.0.41204.256-8.0.50608.0\"
![](/icons/6898new.gif)
Version=\"8.0.50727.42\"/>
</dependentAssembly>
</dependency>
</assembly>
那就又带出了
![](/icons/6898yi.gif)
个问题:那为什么需要重定向呢?为什么链接器不在清单文件中直接指定由安装
![](/icons/6898chengxu.gif)
安装
![](/icons/6898de.gif)
![](/icons/6898chengxu.gif)
集版本呢?原因在于
![](/icons/6898dou.gif)
链接器是从导入静态库中获得所需
![](/icons/6898de.gif)
![](/icons/6898chengxu.gif)
集版本
![](/icons/6898dou2.gif)
这又引出了另外
![](/icons/6898yi.gif)
个问题:为什么链接器要为DLL
![](/icons/6898de.gif)
区别版本使用导入库
![](/icons/6898dou.gif)
而不是安装
![](/icons/6898de.gif)
那个?原因是
![](/icons/6898dou.gif)
这些安装
![](/icons/6898de.gif)
都是重要
![](/icons/6898de.gif)
库
目前为止
![](/icons/6898de.gif)
讨论都是针对托管编译器(C
![](/icons/6898jiajia.gif)
/CLI及旧式语法)
![](/icons/6898dou.gif)
然而
![](/icons/6898dou.gif)
即便本地C
![](/icons/6898jiajia.gif)
开发再高
![](/icons/6898dou.gif)
也有可能被这些新\"特性\"所影响
![](/icons/6898dou2.gif)
如果你
![](/icons/6898de.gif)
代码使用了某个共享
![](/icons/6898de.gif)
VisualStudio本地库(、ATL或CRT)
![](/icons/6898dou.gif)
那么
![](/icons/6898dou.gif)
必须有
![](/icons/6898yi.gif)
个单独
![](/icons/6898de.gif)
.man
![](/icons/6898if.gif)
est清单文件
![](/icons/6898dou.gif)
要么绑定至可执行文件
![](/icons/6898dou.gif)
要么只绑定至
![](/icons/6898yi.gif)
个.exe文件
结论
以前MicrosoftC
![](/icons/6898jiajia.gif)
编译器及链接器
![](/icons/6898de.gif)
各个版本所生成
![](/icons/6898de.gif)
库
![](/icons/6898dou.gif)
都能被加载并运行
![](/icons/6898dou.gif)
但VisualStudio2005中
![](/icons/6898de.gif)
版本14
![](/icons/6898dou.gif)
生成
![](/icons/6898de.gif)
库却无法运行
此处有两个解决思路方法:第
![](/icons/6898yi.gif)
种思路方法是运行链接器两次
![](/icons/6898dou.gif)
![](/icons/6898yi.gif)
次是生成清单文件
![](/icons/6898dou.gif)
其能编译进非托管资源
![](/icons/6898dou.gif)
接着
![](/icons/6898yi.gif)
次是把这个清单绑定至PE文件
![](/icons/6898dou2.gif)
这也是本文所推荐
![](/icons/6898de.gif)
思路方法
![](/icons/6898dou.gif)
![](/icons/6898yinwei.gif)
如果在构造
![](/icons/6898yi.gif)
个具有\"强名称\"
![](/icons/6898de.gif)
![](/icons/6898chengxu.gif)
集
![](/icons/6898dou.gif)
在第 2次
![](/icons/6898diaoyong.gif)
时
![](/icons/6898dou.gif)
就能提供密钥文件或容器
![](/icons/6898de.gif)
名称
![](/icons/6898dou2.gif)
[Page]
另
![](/icons/6898yi.gif)
个思路方法是
![](/icons/6898dou.gif)
使用mt.exe未公开
![](/icons/6898de.gif)
选项来修改
![](/icons/6898chengxu.gif)
集
![](/icons/6898dou.gif)
然而
![](/icons/6898dou.gif)
如果使用链接器来生成
![](/icons/6898yi.gif)
个\"强名称\"
![](/icons/6898de.gif)
![](/icons/6898chengxu.gif)
集
![](/icons/6898dou.gif)
mt.exe
![](/icons/6898de.gif)
动作会使强名称签名无效
![](/icons/6898dou.gif)
且
![](/icons/6898chengxu.gif)
集也不会加载
延伸阅读
- 2011-6-5-- 服务器托管,服务器托管六大优势与虚机托管区别
- 2010-12-9-- 服务器托管租用,服务器租用托管精打细算 选好IDC
- 2011-2-15-- 服务器托管,如何托管服务器才安全
- 2010-12-10-- 服务器托管租用,托管租用服务器 谨慎选择数据中心
- 2010-12-9-- 清除缓存,sqlserver 中一些常看的指标和清除缓存的方法
- 2011-1-28-- 服务器托管租用,服务器托管和服务器租用问题与建议
- 2010-12-7-- 亚马逊服务器,亚马逊宣布提供DNS服务器托管业务
- 2011-1-26-- 服务器托管,服务器托管 警惕奸商忽悠
- 2010-12-7-- 亚马逊服务器,亚马逊宣布提供DNS服务器托管业务
- 2010-12-28-- dns缓存,大多企业仍然容易收到DNS缓存中毒攻击
最新评论