views:

2636

answers:

5

Hi! I have C++ project (VS2005) which includes header file with version number in #define directive. Now I need to include exactly the same number in twin C# project. What is the best way to do it?

I'm thinking about including this file as a resource, then parse it at a runtime with regex to recover version number, but maybe there's a better way, what do you think?

I cannot move version outside .h file, also build system depends on it and the C# project is one which should be adapted.

+1  A: 

MSDN tells us:

The #define directive cannot be used to declare constant values as is typically done in C and C++. Constants in C# are best defined as static members of a class or struct. If you have several such constants, consider creating a separate "Constants" class to hold them.

You can create library using managed C++ that includes class - wrapper around your constants. Then you can reference this class from C# project. Just don't forget to use readonly < type > instead of const < type > for your constants declaration :)

aku
+1  A: 

You could always use the pre-build event to run the C preprocessor on the .cs file and the post build event to undo the pre-build step. The preprocessor is just a text-substitution system, so this is possible:

// version header file
#define Version "1.01"

// C# code
#include "version.h"
// somewhere in a class
string version = Version;

and the preprocessor will generate:

// C# code
// somewhere in a class
string version = "1.01";

Skizz

Skizz
+2  A: 

You can achieve what you want in just a few steps:

  1. Create a MSBuild Task - http://msdn.microsoft.com/en-us/library/t9883dzc.aspx
  2. Update the project file to include a call to the task created prior to build

The task receives a parameter with the location of the header .h file you referred. It then extracts the version and put that version in a C# placeholder file you previously have created. Or you can think using AssemblyInfo.cs that normally holds versions if that is ok for you.

If you need extra information please feel free to comment.

smink
+1  A: 

You can write simple C++/C utility that include this .h file and dynamically create file that can be used in C#.
This utility can be run as a part of C# project as a pre-build stage.
This way you are always sync with the original file.

Ilya
A: 

I wrote a python script that converts #define FOO "bar" into something usable in C# and I'm using it in a pre-build step in my C# project. It works.

# translate the #defines in messages.h file into consts in MessagesDotH.cs

import re
import os
import stat

def convert_h_to_cs(fin, fout):
 for line in fin:
  m = re.match(r"^#define (.*) \"(.*)\"", line)
  if m != None:
   if m.group() != None:
    fout.write( "public const string " \
    + m.group(1) \
    + " = \"" \
    + m.group(2) \
    + "\";\n" )
  if re.match(r"^//", line) != None:
   fout.write(line)

fin = open ('..\common_cpp\messages.h')
fout = open ('..\user_setup\MessagesDotH.cs.tmp','w')

fout.write( 'using System;\n' )
fout.write( 'namespace xrisk { class MessagesDotH {\n' )

convert_h_to_cs(fin, fout)

fout.write( '}}' )

fout.close()

s1 = open('..\user_setup\MessagesDotH.cs.tmp').read()

s2 = open('..\user_setup\MessagesDotH.cs').read()

if s1 != s2:
 os.chmod('..\user_setup\MessagesDotH.cs', stat.S_IWRITE)
 print 'deleting old MessagesDotH.cs'
 os.remove('..\user_setup\MessagesDotH.cs')
 print 'remaming tmp to MessagesDotH.cs'
 os.rename('..\user_setup\MessagesDotH.cs.tmp','..\user_setup\MessagesDotH.cs')
else:
 print 'no differences.  using same MessagesDotH.cs'
Corey Trager