【发布时间】:2016-06-10 05:00:52
【问题描述】:
我有一个主要用 C# 编写的项目。我需要为这个项目的 API 的所有错误号“定义”定义一个类。我试图避免编写/更改我的许多代码生成器之一来实现这一点。
我想做的是能够将#include 内容(如错误文件)直接导入 C/C++ 项目。我在 C# 中对它们进行了如下定义,并且我没有为您将在此处看到的内容使用枚举:
using System;
namespace ProjectAPI {
[Serializable]
public sealed class ProjectError {
public enum ProjectErrorClass {
None = -1,
Undefined = 0,
Login,
Store,
Transaction,
Heartbeat,
Service,
HTTPS,
Uploader,
Downloader,
APICall,
AutoUpdate,
General
}
public enum ProjectErrorLevel {
Unknown = -1,
Success = 0,
Informational,
Warning,
Critical,
};
/// <summary>
/// PROJECT_ERROR_BASE - This is the base for all Project defined errors in the API. Project Errors are defined as follows:
/// ProjectAPI error values are 32 bit values defined as follows:
/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
/// +---+---------------+-----------------------+------------------+
/// |Sev|Error Code Base| Error Class |Unique Error Code |
/// +---+---------------+-----------------------+------------------+
/// where
///
/// Sev - is the severity code of the error (2 bits), and is defined as follows:
/// 00 - Success (non-fatal) 0x00
/// 01 - Informational 0x01
/// 10 - Warning 0x02
/// 11 - Error 0x03
///
/// Error Code Base - is the starting point of all Project Errors, and is set at 0xA4 (8 Bits).
///
/// Error Class - is the error class, or API "Module" that caused the error (12 bits).
///
/// Code - the unique error code (10 bits). (0 - 1,023 (0x3FF)).
/// </summary>
private static readonly int ERR_SHIFT = 0x1E;
private static readonly int BASE_SHIFT = 0x16;
private static readonly int CLASS_SHIFT = 0x06;
private static readonly int PROJECT_SEV_SUCCESS = 0x00;
private static readonly int PROJECT_SEV_INFO = 0x01;
private static readonly int PROJECT_SEV_WARN = 0x02;
private static readonly int PROJECT_SEV_ERROR = 0x03;
private static readonly int PROJECT_ERROR_BASE = 0xA5;
/// <summary>
/// Project Error Class Constants:
/// </summary>
private static readonly int PROJECT_ERROR_CLASS_UNDEF = 0x0010; /// Undefined.
private static readonly int PROJECT_ERROR_CLASS_LOGIN = 0x0020; /// LoginClass Error.
private static readonly int PROJECT_ERROR_CLASS_STORE = 0x0040; /// Store Error.
private static readonly int PROJECT_ERROR_CLASS_TRANS = 0x0080; /// Transaction Error.
private static readonly int PROJECT_ERROR_CLASS_HEART = 0x0100; /// HeartBeat (Project Health Monitor) Error.
private static readonly int PROJECT_ERROR_CLASS_SERV = 0x0200; /// Service Error.
private static readonly int PROJECT_ERROR_CLASS_HTTP = 0x0400; /// HTTP/HTTPS Error.
private static readonly int PROJECT_ERROR_CLASS_UPLOAD = 0x0800; /// Upload (Transactions) Error
private static readonly int PROJECT_ERROR_CLASS_DOWNLOAD = 0x1000; /// Download (Transactions) Error
private static readonly int PROJECT_ERROR_CLASS_APICALL = 0x2000; /// API Command/call error.
private static readonly int PROJECT_ERROR_CLASS_UPDATE = 0x4000; /// Auto-Updater Errors.
private static readonly int PROJECT_ERROR_CLASS_GEN = 0x8000; /// General Error.
public static readonly int PROJECT_ERROR_UNKNOWN_ERROR = ProjectErrCode(PROJECT_SEV_ERROR, PROJECT_ERROR_CLASS_GEN, 0x001);
// Was...
// (((PROJECT_SEV_ERROR << ERR_SHIFT) | PROJECT_ERROR_BASE << BASE_SHIFT) | ((PROJECT_ERROR_CLASS_UNDEF << CLASS_SHIFT) | 0x0001));
public static readonly int PROJECT_ERROR_UNKNOWN_HEARTBEAT_ERROR = ProjectErrCode(PROJECT_SEV_ERROR, PROJECT_ERROR_CLASS_HEART, 0x001);
...Snip...
...
我意识到我可以在 Enums 中添加其他内容,但是我的目标是也能够使用 C++ 编译器编译此源代码。 (上面的示例中缺少一些函数,即ProjectErrCode(),它在从 API 调用时构建错误代码 OTF 的最终整数值。)
我正在构建在 cmets 中看到的错误常量,我可以回到那个,但我宁愿编写类似的类 - 一个在 C# 中,一个在 C++ 中,可以构造/解构错误代码。我的函数返回错误的严重性、错误类等。开发者可以忽略它、记录它、将它传递给 UI 等等。
如果我只有 5 或 10 个错误代码,这不是问题。但我有超过 100 个,真的不想维护一个包含重复信息的 .cs 和 .h 文件。我可以在 .h 文件中管理它们并让 CS 代码读取它们,但这几乎与编写(修改)代码生成器一样多。
我怎样才能#define 获得单个源文件,以便 C# 编译器可以编译它,就像 C/++ 编译器一样?我可以简单地#include "ProjectErrors.cs" - 文件名在那里不是问题。我开始以为我可以通过#define'ing 像using System; 这样的东西来做到这一点,但几乎都挂在那里了。
【问题讨论】:
-
大多数情况下,它只是将每个不在 C++ 中的单词和
#define放在一个空白字符串中。我认为没有办法处理[Serializable]。 -
如您所说,代码生成器是一种解决方案。我认为没有其他方法
-
@DarkFalcon:
#ifndef CPP \\\ [Serializable] \\\ #endif \\\ class XYZ { .... }现在#define CPP仅在 C++ 端,并在 C# 端保持 CPP 未定义 -
@quetzalcoatl:当然可以,但这需要修改他的代码生成器。
-
感谢 Dark Falcon,是的,实际上,[Serializable] 可能不需要,但由于它用于远程处理,我不确定......我真的希望这不是t 一个问题,如果项目更大,我会用 Native C++ 编写它,然后编写 C# 包装器.. 唉......
标签: c# c++ enums code-sharing