简体   繁体   中英

Porting #define from C++ to C#

I have an old MCPP project which was used as a communication layer between C++ code which runs on machines and C# which runs on a desktop computer. Recently we decided to try and kill this "glue" project.

This project has in it a few lists of constants which are used in the communication and these will be preferably used as an external link in both, C++ and C#.

A colleague how has done a similar thing before used the following trick to keep changes to the constants in one place:

#if !__cplusplus
    public const string
#else
    static const TCHAR* const
#endif
                                XML_V1_TagRoot = "r";

The __cplusplus is set depending on the compiler, so the prepeocessor makes each compiler see what it can compile.

Now I have the problem with a bunch of #define statements of the type:

#define TX_TAG2xHWID_PARAMETER  _T("PR")

Where _T() is a macro. So I tried the following:

#if __cplusplus
    #define     TX_TAG2xHWID_PARAMETER _T("PR")
#else
    internal const string   TX_TAG2xHWID_PARAMETER = "PR";
#endif

Which does not work because C# has no value for the defines. source

Then I tried:

#if __cplusplus
    #define                 TX_TAG2xHWID_PARAMETER \
#else
    internal const string   TX_TAG2xHWID_PARAMETER =
#endif

#if __cplusplus
                                                _T(\
#endif
                                                    "PR"
#if __cplusplus
                                                        )
#else
                                                        ;
#endif

Here the problem is that C# does not allow a multiline #define .

Basically the issue is that a #define is a preprocessor instruction in itself, but should be executed only if the file is compiled in a C++ project.

I have also played with the idea of making the C# project think it is a comment, with placing /* and */ into a different #if , but I had no success there.

So, does anyone know a solution how I can make the C# compiler not complain about that line which it should never try to compile?

One possible solution is to give C# a function called _T (which just returns its argument), and then stick with the original approach:

#if !__cplusplus
    public const string
#else
    static const TCHAR* const
#endif
                                TX_TAG2xHWID_PARAMETER = _T("PR");

A completely different approach (which is why it is a separate answer), is to generate both the C++ header file and the C# file at build time with a script. That way the actual source that needs editing is something like

output_text XML_V1_TagRoot "r"
output_text TX_TAG2xHWID_PARAMETER "PR"
output_int  FUNKY_INT_PARAM 43

and the messy #if s are all produced by the script.

Have you considered putting the strings in resources? Both of those can be accessed from C++ or C# using symbolic names and the strings will live in one place and have no issues due to differences in string escapes.

You can also introduce a step into your build that takes a list of strings and their symbolic names and creates two output files: one for C++ and one for C# with an important comment at the top:

// This file is machine generated. To add a constant, edit the file xxxxx
// and rebuild with the command xxxx

This will, at the very least, put all the strings and symbol names in exactly one place at the cost of slightly complicating your build process. And yes, this is exactly the same as using string resources except that you're using a home-cooked tool/script.

Unless you have a good reason to keep TX_TAG2xHWID_PARAMETER and similar parameters inlined, you might replace your

#if __cplusplus
    #define     TX_TAG2xHWID_PARAMETER _T("PR")
#else
    internal const string   TX_TAG2xHWID_PARAMETER = "PR";
#endif

with

#if __cplusplus
    LPCTSTR     TX_TAG2xHWID_PARAMETER = _T("PR");
#else
    internal const string   TX_TAG2xHWID_PARAMETER = "PR";
#endif

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM