【问题标题】:Generate compiler error if platform target is not x86如果平台目标不是 x86,则生成编译器错误
【发布时间】:2016-10-12 08:35:11
【问题描述】:

如果平台目标未设置为 x86,如何生成编译器错误?

动机:一种特定的方法动态加载 32 位 COM dll。如果项目是为“x64”或“Any CPU”构建的并且在 64 位环境中运行,那么在运行时加载 COM 对象自然会失败。我想要一个编译时检查以确保这不会发生。

这旨在对项目设置进行安全检查,完全封装在需要 32 位的源文件中。所以我无法接受需要在项目设置中定义条件编译符号的解决方案(比如this)。

【问题讨论】:

  • 这看起来很像 XY 问题。我建议通过 COM+ (DCOM) 在专用服务器进程中托管您的 COM 组件。这样,dllhost 进程将围绕您的组件启动,并将编组调用。由于这些是跨进程调用,因此您的 C# 项目的位数将不再重要。
  • @FrédéricHamidi 感谢您的建议。这是我想避免的——在 64 位上运行它没有任何优势。
  • 您可以按照here 的讨论评估 IntPtr.Size。
  • @AxelKemper 我不认为 IntPtr.Size 可以在编译时进行评估。

标签: c#


【解决方案1】:

您可以编写一个 Roslyn 诊断分析器来执行此操作。

首先,在您的代码中编写一些内容以进行搜索。例如,您可以使用属性。它可以是程序集级别的属性,例如:

[assembly: Require32bit]

它也可以是你应用到类的属性,甚至是调用 COM 组件的方法,由你选择。

然后编写一个分析器来搜索它的存在。在分析器中,您可以使用Compilation.Options.Platform 属性来确定平台。该编译可从例如SyntaxNodeAnalysisContext

【讨论】:

  • 您必须将分析器作为 Nuget 包添加到项目中。这并不像看起来那么糟糕,因为您使用的属性需要来自某个地方,并且它可能位于同一个 Nuget 包中。 (或者,您可以使用 .vsix 在 Visual Studio 中安装分析器,但对于这种情况,我需要 Nuget 解决方案。)您需要阅读 Roslyn 分析器。这应该可以帮助您入门:bing.com/search?q=developing+roslyn+diagnostic+analyzer
  • 好吧,如果源代码需要引用某个 DLL,那么其他项目需要引用该 DLL 才能编译,对吗?它引用的any DLL 就是这种情况,而不仅仅是包含该属性的DLL。所以他们无论如何都需要添加参考。这就是这一切的美妙之处:如果他们通过 Nuget 包引用具有属性的 DLL,并且该 Nuget 包还包含分析器,则分析器将在每次构建时自动运行!
  • 不,COM 对象是动态加载的。 (如Type.GetTypeFromProgID()Activator.CreateInstance()。)尽管对于您描述的情况,解决方案非常好。
  • 是的,但属性不是。
  • Require32BitAttribute 不存在。你会创造它。因此,为了编译使用它的代码,您必须引用包含它的程序集。该程序集位于还包含分析器的 Nuget 包中。
【解决方案2】:

您是否尝试过类似的方法:

#if PLATFORM_X86
    #error Target platform needs to be x86!
#endif

【讨论】:

  • 说实话,我还没有完全测试过这个,但几个月前有类似的东西。我可以在回家后(6 小时内)试试,如果这对你有用?
  • 很遗憾,它不起作用。没有 PLATFORM_X86 符号。 (是的,我可以定义一个,但是当代码在另一个项目中使用时没有保护。)
  • 你是不是把它添加为条件编译符号。它位于“构建”选项卡中。
  • 实际上,这是我决定采用的解决方案。我犯了错误说#error This method requires that the platform target is x86. To resolve this error set the platform target and also a PLATFORM_X86 compilation symbol.有点笨拙但应该有效。
猜你喜欢
  • 2020-10-24
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2010-10-06
  • 2016-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多