1

I have a const int that is computed at compile time in my Managed C++ DLL. I need to use this value in an attribute within the C# program that calls it. Initially I had created a static method that returns the const int value but C# doesn't see this as a compile time const. I also tried declaring it as a const int within the DLL namespace

// C++
namespace MyNameSpace {
    const int AttributeConstValue = 15 + sizeof(int);
 . . .
}

Attempts to access MyNameSpace.AttributeConstValue from C# returns "does not exist in namespace MyNameSpace"

Is there a way to pass a const to C# and have it see it as a const expression?

JonN
  • 2,498
  • 5
  • 33
  • 49

3 Answers3

2

You must use the C++/CLI literal keyword to declare public constants that are visible to other managed compilers. And it must appear inside a ref class. Like this:

namespace Example {
    public ref class Constants {
    public:
        literal int AttributeConstValue = 15 + sizeof(int);
    };
}

Sample C# usage:

[MyAttribute(Example.Constants.AttributeConstValue)]
// etc..

Beware that this is fairly dangerous. The literal value gets compiled into the C# assembly's metadata without a reference to your C++/CLI assembly. So if you make a change to this declaration but don't recompile the C# project then you'll have a nasty mismatch. But as long as you need to use it in an attribute declaration then there's no fix for this.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • We were posting same answer simultaneously. :) Thanks! – JonN Jun 26 '12 at 22:28
  • The unsafe condition is mitigated in my case by both the C++ DLL project and C# projects being built within the same solution with the C# project depending on C++ DLL. – JonN Jun 26 '12 at 22:38
0

Const is different then other declaration. When code start to compile - the compiler just replace all places where you use the const with it's value - because const value could not be changed. It's resolved once - at compilation time and stays that way. I don't really remember but I think optimization flag even delete const declaration from code. So the situation is like this: when you done compiling you can not change it - so you first attempt - to return it in some function or getter/setter is right one. Obviously you can not return it to const variable because to-return-it you must compile the program and when you compile the program... you get the point :)

P.S. Don't know about C++ but in C# const is class members and could not be declared in namespace

Alex F
  • 3,180
  • 2
  • 28
  • 40
  • You missed that I need to use this constant as the value of a field in an C# **attribute** and using my first technique the C# compiler complained that it was not a constant expression. See my answer for a solution to this. Here is the C# usage [MarshalAs(UnmanagedType.ByValArray, SizeConst=MyNameSpace.ConstClass.AttributeConstValue] – JonN Jun 26 '12 at 21:29
  • @JonN: A `const` variable is *not* a constant expression. The compiler wants a `constant expression` as it must have this available at compile time. – Ed S. Jun 26 '12 at 21:35
  • @Eds That's true but I wasn't sure how to create a symbolic constant that was usable from C#. Using the **literal** keyword as Hans points out, in managed C++ makes AttributeConstValue a symbol that is a constant expression. – JonN Jun 26 '12 at 22:30
  • @JonN: Yep, I didn't know about `literal` (I know little to nothing of C++/CLI) – Ed S. Jun 26 '12 at 22:37
0

Found answer HERE

// C++ Const declaration
namespace MyNameSpace {
public ref class ConstClass {
public:
     literal int AttributeConstValue = 15 + sizeof(int);
. . .
}

// C# Usage
[MarshalAs(UnmanagedType.ByValArray, SizeConst=MyNameSpace.ConstClass.AttributeConstValue)]
public byte [] results;

Referencing MyNameSpace.ConstClass.AttributeConstValue as field value for C# attribute works fine using this technique. The value is seen as a compile time constant expression.

Community
  • 1
  • 1
JonN
  • 2,498
  • 5
  • 33
  • 49