извиняюсь за поздний ответ, когда я обещал один ранее.
У меня есть идея использовать компилятор кода времени выполнения, а также рефлексию для динамической генерации класса, который содержит все эти константы.
Итак, шаги (или псевдокод), как я вижу это:
- Для каждого файла .h прочитайте все строки, которые начинаются с
#define
, и сохраните их. - Используя
Microsoft.CSharp.CSharpCodeProvider()
и пустой файл шаблона, скомпилируйте DLL в памяти, которая содержит класс, который предоставляет константы стиля public const int ALPHA_REACTOR_CODE = 99641;
. - Используйте
Assembly.GetType(string)
, чтобы получить тип вашего сгенерированного класса - Используйте Reflection и метод, который принимает имя константы для доступа к значению.
Так что, если это наш план атаки, вот несколько фрагментов кода, которые могут вам помочь.
1.Загрузка файлов .h Это довольно простое чтение файлов, ключевая хитрость состоит в том, чтобы отфильтровать ваши строки по #define
и затем проанализировать Dictionary<string, int>
.
lines.Where(line => line.StartsWith("#define", true, CultureInfo.CurrentCulture))
.Select(line => line.Split(' ').Skip(1))
.ToDictionary(lineParts => lineParts.First(), lineParts => int.Parse(lineParts.Last()));
. Это сгенерирует словарь.из всех ваших определений.Возможно, вы захотите сделать .Distict()
вызов до .ToDictionary()
на тот случай, если есть повторяющиеся определения.
2.Генерация сборки Здесь вы используете Microsoft.CSharp.CSharpCodeProvider()
для генерации сборки в памяти.Хитрость заключается в том, чтобы иметь файл «GenerateCode.cs», который содержит базовую структуру для класса.Это должно быть установлено как EmbeddedResource, иначе он будет пытаться скомпилироваться (что не будет работать).
using System;
namespace GeneratedCode
{{
public class GeneratedConstants
{{
{0}
}}
}}
Вы заметите {0}
, мы используем это с string.Format
длявставьте константы в файл.
Используйте assembly.GetManifestResourceStream()
, чтобы получить поток этого файла шаблона, и обычный StreamReader
, чтобы прочитать это в одну большую строку в памяти.
Генерация константиспользуя StringBuilder
и базовое string.Format()
форматирование в сочетании со словарем значений.
StringBuilder builder = new StringBuilder();
foreach (var constant in dict)
{
builder.AppendFormat(CultureInfo.CurrentCulture, "public const int {0} = {1};", constant.Key, constant.Value);
}
Затем просто используйте string.Format (), чтобы вставить строку построителя в сгенерированную строку класса (используя {0}
)
Тогда вам просто нужно использовать Microsoft.CSharp.CSharpCodeProvider()
для генерации сборки в памяти.
using (CSharpCodeProvider provider = new CSharpCodeProvider())
{
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Core.dll");
CompilerResults results = provider.CompileAssemblyFromSource(parameters, sourceCode);
}
3 & 4. Теперь с помощью Reflection иметь сборку, которая содержит тип с определенными в нем константами, вы можете использовать assembly.GetType("GeneratedCode.GeneratedConstants");
, чтобы получить тип, и использовать Reflection, чтобы вывести константы, по одной или все вместе.
ЕстьПосмотрите на этот пост, который описывает, как получить const, используяотражение: http://weblogs.asp.net/whaggard/archive/2003/02/20/2708.aspx
Ну, я надеюсь, это поможет вам.Это не слишком сложное решение, но имеет несколько движущихся частей.
Удачи!