- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在编译托管 DLL 项目时遇到问题。该解决方案由两个项目组成,第一个是用 C# 编写的 .NET DLL,另一个是直接引用 C# 项目的托管 C++ DLL。
这两个项目/DLL 都使用磁盘上的 snk 文件进行强命名。 C# dll 的目标框架为 "AnyCPU"
,而 Manage C++ 项目编译两次,一次用于 x86 目标,另一次用于 x64。
我的问题是,当我编译托管 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 位)
我不确定为什么它使用 AnyCPU 配置以及 64 位首选注释的确切含义?
我还想提一下,我的项目是针对 C# 项目的 .NET Framwork 2.0 构建的,而托管 C++ 项目是针对 v90 平台工具集构建的。我正在使用在 Windows 7 64 位计算机上运行的 Visual Studio 2010。
谁能告诉我为什么会这样,我该如何解决这个问题?
最佳答案
这只是汇编中的 COR header 如何指示所需处理器架构的结果。您可以在 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 位操作系统上运行。 Kaboom 在 32 位操作系统上,程序失败并出现错误 11,ERROR_BAD_FORMAT,“试图加载格式不正确的程序”。
这回答了您的问题,它与强名称没有任何关系。
关于c# - x86 程序集的 null PublicKeyToken,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21524702/
每个签名的 .NET 都有一个公钥 token (8 个字节)和一个公钥(128 个字节)。 两者有什么区别,为什么我们需要两个公共(public)“ key ”? 最佳答案 公钥 token 只是
如何从 snk 文件中获取 PublicKeyToken?使用命令行工具。我想过使用sn.exe,但是,找不到合适的参数。 最佳答案 如果您想使用 sn.exe工具: sn -p yourkey.sn
如果我从我的项目 C# 文件夹中打开 Resources.resx,我会看到类似这样的内容: ..\Resources\picture.png;System.Drawing.Bitmap,
Could not load file or assembly 'NCrawler.GeckoProcessor, Version=3.0.0.0, Culture=neutral, PublicKe
我需要在我的 web.config 文件中重新创建一个如下所示的提供程序: 但是,我收到一个运行时错误,提示无法加载此程序集,我认为这是因为我的 PublicKey
我在一个遗留项目上工作,必须支持同一个 dll 的 8 个不同版本。我可以访问库源代码,因此我可以自己构建这些 dll。 dll 是强签名的,每个都有自己的版本号 3.6.0.0、3.7.0.1 等。
我在编译托管 DLL 项目时遇到问题。该解决方案由两个项目组成,第一个是用 C# 编写的 .NET DLL,另一个是直接引用 C# 项目的托管 C++ DLL。 这两个项目/DLL 都使用磁盘上的 s
我正在使用以下代码: AppDomain.CurrentDomain.AssemblyLoad += (sender, args) => { var token = args.LoadedAs
我正在尝试使用这篇博文中的建议获取针对 Asp.Net Identity 的瑞典语本地化错误消息:How to localize ASP.NET Identity UserName and Passw
我的 app.config 中有以下内容。 ... Fusion 日志记录告诉我它没有在 bin2 中查
希望我什至能正确地问我的问题。我在尝试序列化特定对象时遇到以下异常(我熟悉使用标准 [Serializable] 属性) A first chance exception of type 'Syste
我正在按照 2006 年 Microsoft .Net 类(class)工作簿中的说明进行其中一项练习。 (具体来说,这门类(class)是 MS2349B,我正在做模块 4 练习 2。)。这些练习似
{"Could not load file or assembly 'AssemblyName, PublicKeyToken=null' or one of its dependencies. Th
我们有一个 asp.net 4.0 项目,它使用几个依赖于 log4net 版本 1.2.10.0 的框架。今天我尝试包含一个依赖于 log4net 版本 1.2.11.0 的新框架,从那时起我就陷入
我正在使用 PRISM 和我在 CodePlex 中找到的新控件:WPF 属性网格 http://wpg.codeplex.com/ 当我测试 DEMO 时,一切进展顺利。 我还没有开始使用 PRIS
我向我的应用程序添加了一条 UPDATE 语句,该语句运行良好。它正确更新数据库,除了四个错误消息之外,我没有看到任何问题。这是什么意思? Error 1 Type Microsoft.Dat
是否可以从 GAC 中卸载所有具有特定 PublicKeyToken 的程序集? 我接受命令行(gacutil.exe 等)或通过 C# 的解决方案。 编辑: 仅供引用,我可以通过 Windows 资
我必须在我的项目中使用一些引用程序集 XXXXX 的 dll 文件。我现在在我的项目中有这个程序集的更新版本,但是当我运行我的项目时我得到错误:Could not load file or assem
使用来自 Docusign、Twilio 和 Auth0 的 API。所有 3 个都将 RestSharp.dll 作为依赖项。 如果我使用 Docusign 包中包含的 RestSharp.dll,
我有一个在开发环境中引用此程序集的应用程序: name="Microsoft.Data.SqlXml" culture="neutral" publicKeyToken="89845dcd8080cc
我是一名优秀的程序员,十分优秀!