Для обращения к проблемам переменчивости, можно объявить X и Y как финал. Например:
class Data {
public final int x;
public final int y;
public Data( int x, int y){
this.x = x;
this.y = y;
}
}
Код вызова, который пытается записать в эти поля, доберется, ошибка времени компиляции "поля x объявляется финалом; не может быть присвоен".
клиентский код может тогда иметь удобство 'стенографии', которое Вы описали в своем сообщении
public class DataTest {
public DataTest() {
Data data1 = new Data(1, 5);
Data data2 = new Data(2, 4);
System.out.println(f(data1));
System.out.println(f(data2));
}
public int f(Data d) {
return (3 * d.x) / d.y;
}
public static void main(String[] args) {
DataTest dataTest = new DataTest();
}
}
Вы всегда должны использовать copy_from_user
и аналогичные для доступа к памяти пользовательского пространства из пространства ядра, независимо от того, как вы получили указатель. Поскольку b
является указателем на память пользовательского пространства, вы должны использовать copy_from_user
для доступа к нему.
Эти функции выполняют две важные дополнительные задачи:
copy _ * _ user
имеет специальное переопределение, которое сообщает обработчику PF, что все в порядке, и что с ошибкой следует обращаться как обычно; и в случае, если сбой не может быть устранен с помощью ввода-вывода (то есть, что обычно вызывает SIGSEGV
или SIGBUS
), вернуть вместо этого код ошибки, чтобы вызывающий пользователь мог выполнить любую необходимую очистку прежде чем вернуться в пользовательское пространство с помощью -EFAULT
. Вы правы в своем предположении. Если вам нужно получить доступ к значению * b
, вам нужно будет использовать copy_from_user
(и copy_to_user
, чтобы обновить его обратно в пользовательском процессе).