如何在C#中跳过C++预处理指令

huangapple go评论68阅读模式
英文:

How to skip a C++ preprocessor directive in C#

问题

以下是您要翻译的内容:

我试图在C++和C#中使用相同的类。我正在使用预处理器指令来处理代码差异。然而,即使它们位于#if #endif部分中,我也无法跳过C++指令(如#include或#define)。

以下代码在C++中编译,但在C#中不编译:

#if !NET
#pragma once
#include <string>      //<-- C# error CS1024: Preprocessor directive expected
#define public public: //<-- C# error CS1025: Single-line comment or end-of-line expected
#endif

#if NET
namespace A.B {
#else
namespace A::B {
   using namespace std;
#endif
   class C {
      string str;
      public C() {str = "test";}
   };
}

#if !NET
#undef public
#endif

问题:

  • 为什么我不能这样做?
  • 为什么C#预处理器尝试理解位于#if !NET部分内的#include或#define指令?
  • 有没有办法做到这一点?

编辑:

哎呀!重新阅读C#标准规范的第6.5.5章,我注意到以下段落:

> 剩余的条件部分将被跳过,源代码中不会生成任何标记,除了那些用于预处理指令的标记。因此,跳过的源代码,除了预处理指令外,在词法上可能是不正确的。跳过的预处理指令必须在词法上正确,但不会被其他方式处理。在正在跳过的条件部分中,任何嵌套的条件部分(包含在嵌套的#if...#endif结构中)也将被跳过。

  • 所以,好的,我的第一个问题得到了答案。
  • 第二个问题呢:为什么预处理指令必须在词法上正确?
  • 不过,有人知道如何避免这个限制吗?如何使上述代码工作?
英文:

I am trying to use the same class in C++ and C#. I am using preprocessor directives to scape code differences. However, I cannot skip C++ directives (as #include or #define) even when they are inside an #if #endif section.

The following code compiles in C++, but not in C#:

#if !NET
#pragma once
#include <string>      //<-- C# error CS1024: Preprocessor directive expected
#define public public: //<-- C# error CS1025: Single-line comment or end-of-line expected
#endif

#if NET
namespace A.B {
#else
namespace A::B {
   using namespace std;
#endif
   class C {
      string str;
      public C() {str = "test";}
   };
}

#if !NET
#undef public
#endif

Questions:

  • Why can I not do this?
  • Why C# preprocessor tries to understand #include or #define directives if they are inside an #if !NET section?
  • Is there anyway to do it?

EDIT:

Ouch! Rereading chapter 6.5.5 of the C# standard specification, I notice the following paragraph:

> Any remaining conditional sections are skipped and no tokens, except those for pre-processing directives, are generated from the source code. Therefore skipped source code, except pre-processing directives, may be lexically incorrect. Skipped pre-processing directives shall be lexically correct but are not otherwise processed. Within a conditional section that is being skipped any nested conditional sections (contained in nested #if...#endif constructs) are also skipped.

  • So, ok, my first question is answered.
  • What about the second one: Why pre-processing directives shall be lexical correct?
  • However, does anybody know how to avoid this limitation? How to make the above code work?

答案1

得分: 0

终于,我找到了一种使用两个文件解决这个问题的方法:

注意: 这可能不是最佳的想法,但我找不到比这更好的方法。

/*** myfile.hpp ***/
#pragma once

#include <string>

#define public public:
#include "myfile.cs"
#undef public

/*** myfile.cs ***/
#if NET
namespace A.B {
#else
namespace A::B {
   using string = std::string;
#endif
   class C {
      string str;
      public C() {str = "test";}
   };
}

使用这两个文件,C++ 中应该包括myfile.hpp,而在C#中只需要myfile.cs

这个想法来自于这里:https://stackoverflow.com/a/56839291/13087883

英文:

Finally, I have found a method to solve this issue using two files:

Note: It may not be the best idea, but I can't find a better one than this.

/*** myfile.hpp ***/
#pragma once

#include &lt;string&gt;

#define public public:
#include &quot;myfile.cs&quot;
#undef public

/*** myfile.cs ***/
#if NET
namespace A.B {
#else
namespace A::B {
   using string = std::string;
#endif
   class C {
      string str;
      public C() {str = &quot;test&quot;;}
   };
}

With these two files, on C++ myfile.hpp should be included, and on C# only myfile.cs is needed.

The idea is taken from here: https://stackoverflow.com/a/56839291/13087883

huangapple
  • 本文由 发表于 2023年6月9日 00:13:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76433844.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定