#c# #expression #ref
Вопрос:
Я пишу специальный компилятор для управления машинами. С одной стороны, это должно генерировать машинный код из кода C#, с другой стороны, тот же код должен использоваться для моделирования.
Определение памяти получит адрес через менеджер (для машинного кода), но в моделировании это должно содержать значение.
В коде иногда вместо значения необходимо передавать адрес. Если у меня есть вызов (имя переменной и т.д.) Я могу сам решить этот адрес в симуляции.
Граничные условия:
- для передачи я открыт для всех идей!!!
- из-за смещений массива в старой системе мне приходится обращаться к массивам с помощью методов, поэтому метод обращается
- чтобы передать их методам по ссылке как прямое значение, метод должен быть запрограммирован как метод ‘ref’
- код должен автоматически корректироваться при изменении переменных (например, переименовании в Visual Studio).
Я отверг следующие подходы:
передача в виде строки
-> не обновляется при переименовании, не компилируется
double addr = getAddress3("Mem.PROBE_SET[1]");
передача в виде строки с именем
-> возможно, но не легко использовать
double addr = getAddress3($"{nameof(Mem)}.{nameof(Mem.PROBE_SET)}[1]");
private double getAddress3(string expression)
{
// Resolve text Expression
//double addr = MemoryResolver.resolveExpression(expression);
return 0.0;
}
Мое реальное решение, в качестве примера кода:
GetAddress2 был бы моим предпочтительным решением, потому что вызов такой же, как и тогда, когда я хочу обратиться к sepicher как к значению, и также очень короткий. К сожалению, у меня здесь проблема с «ссылкой»! У кого-нибудь есть идеи, как я мог бы сделать это лучше?
public class Test
{
private ExampleMemory Mem = new ExampleMemory();
public Test()
{
// booth calls could compile, but no info about anonymus method content in GetAddress
double addr1 = GetAddress(() => Mem.getProbePos(1));
double addr2 = GetAddress(() => Mem.PROBE_SET[1]);
// only addr4 could compile, error CS8153 because ref is used
//double addr3 = GetAddress2(() => Mem.getProbePos(1)); // Error CS8153
double addr4 = GetAddress2(() => Mem.PROBE_SET[1]); // Works fine
}
private double GetAddress(Func<double> func)
{
// no access to source call.... :-( cannot resolve memory
return 0.0;
}
private double GetAddress2(Expression<Func<double>> expr)
{
string info = expr.Body.ToString();
// Infos from Call available => Here i can work with Men.PROBE_SET[1] info and can resolve the memory internally....
return 0.0;
}
}
public class ExampleMemory
{
private int[] PROBE_POS = new int[4]; // with array offset
public int[] PROBE_SET = new int[4]; // without offset => direct access
[ArrayOffsetAttribute(Offset = 1)]
public ref int getProbePos(int index)
{
return ref PROBE_POS[index - 1];
}
}
To summarize again what I have in mind,
a solution for:
// Work with the memroy value
var val = Mem.getProbePos(3); // assign e.g. 23
// Work with address of memory
var addr = GetAddress(/* ... of Mem.getProbePos(3) ...*/); // assign e.g. control address 1723
В методе getAddress я могу использовать что угодно, чтобы получить адрес. Например, через отражение исходной сборки Mem. и так далее. Но мне нужна информация о том, какая память была вызвана.
Мне любопытны ваши идеи и ответы! Заранее большое спасибо.
Обновите, чтобы загрузить вопрос Pizza
В генераторе каждому полю присваивается адрес из класса памяти Examplemory. Затем класс имеет начальный адрес, например 1300.
Сгенерированный код iso из: double value = Mem.PROBE_SET[1];
может выглядеть следующим образом в ISO, где MemoryManager назначает адрес для адреса локальной памяти. #1 = #1305
Но иногда сам адрес, т. е. 1305, используется для функций управления вместо значения, вот как он может выглядеть в C# CNC.G310(val: value, p: GetAddress(Mem.PROBE_SET[1]), sizeType: "L1");
, и это может быть сгенерированный код ISO: G310 #1 P 1305 L1
Поэтому мне нужен сгенерированный адрес моей переменной, но адрес, который я перенес в свой собственный менеджер памяти. Но мне нужно, по крайней мере, указание, какая память (идентификатор и класс, а также индекс для массивов) использовалась.
Комментарии:
1. Я предполагаю, что вам действительно нужен адрес, а не просто способ редактирования уже определенной переменной (если это так, попробуйте
ref
ключевое слово). Но кроме этого не совсем понятно, о чем вы просите (для меня). Вы пытаетесь получить адрес какой-то переменной C#? Если это так, вам, вероятно, понадобитсяunsafe
блок и указатели2. Спасибо за ваш вклад, см. выше мое обновление.