Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# x86程序集的null PublicKeyToken_C#_.net_Visual Studio 2010_Strongname - Fatal编程技术网

C# x86程序集的null PublicKeyToken

C# x86程序集的null PublicKeyToken,c#,.net,visual-studio-2010,strongname,C#,.net,Visual Studio 2010,Strongname,我在编译托管DLL项目时遇到问题。该解决方案由两个项目组成,第一个是.NET中的.NET DLL,另一个是直接引用C项目的管理C++ DLL。p> 两个项目/DLL都使用磁盘上的snk文件进行强命名。C+YDLL有一个目标框架:“代码>”“YANCPU”,同时管理C++项目被编译两次,一个用于x86目标,另一个用于x64。 我的问题是,当我编译托管C++项目时,目标代码是x86平台,结果DLL有一个公钥令牌=null ,如 ILSpy < /C> >所述。当编译以x64平台为目标时,DLL具有正

我在编译托管DLL项目时遇到问题。该解决方案由两个项目组成,第一个是.NET中的.NET DLL,另一个是直接引用C项目的管理C++ DLL。p> 两个项目/DLL都使用磁盘上的snk文件进行强命名。C+YDLL有一个目标框架:“代码>”“YANCPU”<代码>,同时管理C++项目被编译两次,一个用于x86目标,另一个用于x64。 我的问题是,当我编译托管C++项目时,目标代码是x86平台,结果DLL有一个<代码>公钥令牌=null <代码>,如<代码> ILSpy < /C> >所述。当编译以x64平台为目标时,DLL具有正确的PublicKeyToken。我已经检查了我的项目属性,snk文件在
配置属性->链接器->高级->密钥文件
下为两个平台目标正确引用,没有延迟签名;
目标机器
选项也根据所需的编译目标正确设置

以下是我加载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位)

我不知道它为什么使用AnyCPU配置,以及64位首选注释的确切含义

我也提到我的项目是针对.NET项目构建的.NET框架2,而管理的C++项目是针对V90平台工具集构建的。我使用的是在Windows7 64位计算机上运行的VisualStudio2010


有人能告诉我为什么会发生这种情况,以及我如何解决这个问题吗?

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

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

因此,没有什么类似于“64位必需”标志,程序集只能指示“32位”或“无关紧要”。抖动提供了“无关紧要”的胶水,它在运行时生成依赖于体系结构的机器代码。由于未在程序集中启用32BITREQUIRED选项,因此反汇编程序只能显示AnyCPU

下一个细节是可执行文件PE头中的IMAGE\u FILE\u HEADER.Machine字段,它指示可执行文件可以在哪种机器上运行。对于.NET程序集来说,这是一个微弱的信号,因为它们通常不包含任何可执行代码,只包含MSIL。而且它很容易被Windows加载程序忽略,.NET程序集通常将此字段设置为IMAGE\u FILE\u MACHINE\u I386以指示x86。您仍然可以从这样的EXE程序集中获得一个64位进程,当加载这样的EXE时,会发生一些非常英勇的加载程序结构修补。mscoree.dll的作业,即“加载程序垫片”。更多关于这方面的信息,请参阅

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

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


这回答了您的问题,否则它与强名称无关。

感谢您的详细回答,但这只解决了我对(64位首选)注释的担忧。我的实际问题在于
PublicKeyToken=null
,因为我依赖它从客户端应用程序加载程序集。是的,我很高兴你没有问这个问题。当然我不知道,你没有描述你在大会上签字的具体步骤,所以我不知道哪里出了问题。知道不去哪里寻找问题是战斗的50%。继续尝试。尝试启用MSBuild日志记录,然后您可能会发现。