Как передать const int из управляемой C++ DLL в C# для использования в качестве значения поля в атрибуте

У меня есть const int, который вычисляется во время компиляции в моей управляемой C++ DLL. Мне нужно использовать это значение в атрибуте в программе C#, которая вызывает его. Первоначально я создал статический метод, который возвращает значение const int, но C# не видит это как const времени компиляции. Я также попытался объявить его как const int в пространстве имен DLL

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

Попытки получить доступ к MyNameSpace.AttributeConstValue из C# возвращает "не существует в пространстве имен MyNameSpace"

Есть ли способ передать const в C# и увидеть его как выражение const?

3 ответа

Решение

Вы должны использовать буквенное ключевое слово C++/CLI для объявления открытых констант, видимых для других управляемых компиляторов. И это должно появиться внутри класса ref. Как это:

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

Пример использования C#:

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

Остерегайтесь, что это довольно опасно. Литеральное значение компилируется в метаданные сборки C# без ссылки на вашу сборку C++/CLI. Поэтому, если вы внесете изменения в это объявление, но не перекомпилируете проект C#, у вас будет неприятное несоответствие. Но до тех пор, пока вам нужно использовать его в объявлении атрибута, это не исправить.

Const отличается от другой декларации. Когда код начинает компилироваться - компилятор просто заменяет все места, где вы используете const с его ценностью - потому что const значение не может быть изменено. Это решается один раз - во время компиляции и остается таким. Я действительно не помню, но я думаю, что флаг оптимизации даже удалить const объявление из кода. Таким образом, ситуация такова: когда вы завершили компиляцию, вы не можете ее изменить - так что вы сначала пытаетесь - вернуть ее в какую-то функцию, или метод получения / установки является правильным. Очевидно, вы не можете вернуть его const переменная, потому что, чтобы вернуть ее, вы должны скомпилировать программу, и когда вы ее компилируете, вы получаете точку:)

PS Не знаю о C++, но в C# const class члены и не могут быть объявлены в namespace

Нашел ответ ЗДЕСЬ

// 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;

Ссылка MyNameSpace.ConstClass.AttributeConstValue в качестве значения поля для атрибута C# прекрасно работает с использованием этой техники. Значение рассматривается как константа времени компиляции.

Другие вопросы по тегам