Как передать 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# прекрасно работает с использованием этой техники. Значение рассматривается как константа времени компиляции.