簡體   English   中英

在C#和C ++之間共享源文件

[英]Sharing Source files between C# and C++

我有一個主要用C#編寫的項目。 我需要為該項目的API的所有錯誤號“定義”定義一個類。 我試圖避免編寫/修改我的許多代碼生成器之一來實現這一目標。

我想要做的是能夠#include內容(如錯誤defiles)直接進入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的最終整數值。)

我正在構建錯誤常量,如注釋中所示,我可以回過頭來看,但我寧願編寫類似的類 - 一個在C ++中的C#,可以構造/解構錯誤代碼。 我的函數返回錯誤的嚴重性,錯誤類等。 開發人員可以忽略它,記錄它,將其傳遞給UI等。

如果我只有5或10個錯誤代碼,這不是問題。 但我已經超過100,並且真的不希望維護帶有重復信息的.cs和.h文件。 我可以在.h文件中管理它們並讓CS代碼讀取它們,但這幾乎與編寫(修改)代碼生成器一樣多。


我如何#define我的方式到單個源文件,這樣C#編譯器可以編譯它,就像C / ++編譯器一樣? 我只能#include "ProjectErrors.cs" - 文件名不是問題。 我開始認為我可以通過#define using System;這樣的東西來做到這一點using System; 但幾乎掛了。

1)使用預處理器。 一些ifdef和定義應該可以解決問題,但它會非常混亂。

2)使用C ++ / CLI。 C ++ / CLI是C ++的一種變體,它被編譯成.Net程序集。 雖然.Net類型和本機類型是獨立的實體,但它們之間的轉換是可能的。

例如,您將頭文件定義為具有本機枚舉和常量的完全本機代碼; 然后,您可以將此標頭包含到100%本機項目和C ++ / CLI項目中,這也將提供枚舉到相應.Net類型的轉換( 請參閱此線程 )。

如果你不想擁有這個中間轉換層,C ++ / CLI也為你提供了C ++宏的全部功能,所以你可以創建一個包含ENUM_HEADER和CONSTANT等宏的文件,並將它們評估為合適的托管或本機形式。干凈,直接的方式(你不能用C#做,因為它有更弱的預處理器)。 然后,生成的程序集基本上是此標題和適當的宏定義,而不是其他任何內容。

3)在一些外部文件(XML,INI,無論......)中定義值,並且只在C#和C ++中實現加載邏輯(這實際上可能是最干凈的解決方案)。

一種選擇是使用T4 :這是Visual Studio內置的代碼生成語言。 它主要用於C#,但C ++也很有用

您在預處理器上遇到困難的原因之一是C#和C ++具有相同的注釋語法:您無​​法使用注釋為C ++預處理器隱藏不兼容的C#特定語法。 也就是說,你可以嘗試VB :)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM