null x86程序集的PublicKeyToken

时间:2014-02-03 10:21:43

标签: c# .net visual-studio-2010 strongname

编译托管DLL项目时遇到问题。该解决方案包含两个项目,第一个是用C#编写的.NET DLL,另一个是直接引用C#项目的托管C ++ DLL。

两个项目/ DLL都以磁盘上的snk文件命名。 C#dll的目标框架为"AnyCPU",而Manage C ++项目编译两次,一个用于x86目标,另一个用于x64。

我的问题是,当我编译Managed C ++项目以定位x86平台时,结果DLL有一个由PublicKeyToken = null报告的ILSpy。在编译以定位x64平台时,DLL具有正确的PublicKeyToken。我检查了我的项目属性,正确引用了Configuration Properties -> Linker->Advanced->Key File下的两个平台目标的snk文件,没有延迟签名; Target Machine选项也可以根据所需的编译目标正确设置。

这是我加载DLL时ILSpy显示的信息。

对于x64 dll:

// MyDll.x64, Version=1.1.1000.1, Culture=neutral, PublicKeyToken=XXXXXXXXX

// Architecture: x64
// This assembly contains unmanaged code.
// Runtime: .NET 2.0

对于x86 dll:

// MyDll.x86, Version=1.1.1000.1, Culture=neutral, PublicKeyToken=null

// Architecture: AnyCPU (64-bit preferred)
// This assembly contains unmanaged code.
// Runtime: .NET 2.0

我关心的是x86程序集的体系结构描述:AnyCPU (64-bit preferred)

我不确定为什么它使用AnyCPU配置以及64位首选注释意味着什么?

我还想提一下,我的项目是针对C#项目的.NET Framwork 2.0构建的,而Managed c ++项目是针对v90 Platform Toolset构建的。我正在使用在Windows 7 64位计算机上运行的Visual Studio 2010。

有人可以告诉我为什么会这样,我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

这只是程序集中的COR标头如何指示所需的处理器体系结构的结果。您可以在CorHdr.h SDK头文件中看到声明,您可以在计算机上的Windows SDK目录中找到它。您可以使用CorFlags.exe实用程序显示值。

可用的唯一标志是COMIMAGE_FLAGS_32BITREQUIRED。设置后,它向CLR指示您希望以32位模式运行程序,即使在64位操作系统上也是如此。在.NET 4.5,COMIMAGE_FLAGS_32BITPREFERRED中添加了一个额外的标志,它解决了ARM内核的歧义。太多的程序集在32BITREQUIRED周围实际上意味着“需要x86”而不是“需要32位”。

因此没有类似于“64位必需”标志,程序集只能指示“32位”或“无关紧要”。由于抖动提供了“无关紧要”的粘合,它在运行时生成与体系结构相关的机器代码。由于程序集中未打开32BITREQUIRED选项,因此反汇编程序除AnyCPU外无法显示任何其他内容。

下一个细节是可执行文件的PE头中的IMAGE_FILE_HEADER.Machine字段,它指示可执行文件可以在哪种机器上运行。这是.NET程序集的弱信号,因为它们通常不包含任何可执行代码,只有MSIL。并且它很容易被Windows加载程序忽略,.NET程序集通常将此字段设置为IMAGE_FILE_MACHINE_I386以指示x86。你仍然可以从这样的EXE程序集中获得64位进程,当加载这样的EXE时,会发生一些非常英雄的加载器结构修补。 mscoree.dll的工作,“装载机垫片”。有关this post中的更多信息。

由于您在C ++ / CLI项目中定位了x64,因此链接器将IMAGE_FILE_HEADER.Machine设置为IMAGE_FILE_MACHINE_AMD64。反汇编程序看到了这一点,从而产生了“64位首选”注释。

不要被“首选”这个词所愚弄。反汇编程序看起来不够深,看不到你的程序集实际上包含由C ++ / CLI编译器生成的机器代码。他们不喜欢,没有任何反汇编程序会将机器代码反编译回C ++ / CLI源代码。该程序集永远不会在32位操作系统上运行。在32位操作系统上的Kaboom,程序失败,错误11,ERROR_BAD_FORMAT,“试图加载格式不正确的程序”。

这回答了你的问题,它没有与强名称有任何关系。