Ошибка при вызове функции код

Макросы

#define  RES_OK   0   Функция завершилась корректно. Ошибки отсутствуют. Подробнее…   #define  ERROR_ARG_PARAM   0x01180716   Неверный параметр вызова программы. Данная ошибка возникает, когда производится вызов программы с неверным количеством параметров argc и указателем argv на массив параметров вызова программы. Подробнее…   #define  ERROR_DAT_TYPE   0x04012020   Неверный тип данных. Данная ошибка возникает при сохранении данных в бинарный файл, когда параметр, задающий тип данных в памяти (вещественные или комплексные) задан неверно. Подробнее…   #define  ERROR_DIV_ZERO   0x04102226   Ошибка деления на ноль. Функция возвращает данную ошибку, если в вычислительном алгоритме возникло деление на ноль. Подробнее…   #define  ERROR_ELLIP_MODULE   0x05121315   Модуль эллиптического интеграла Якоби должен быть от 0 до 1. Данная ошибка возникает при расчете эллиптических функций Якоби при неверном задании параметра эллиптического модуля. Функция завершает работу и возвращает данный код ошибки. Подробнее…   #define  ERROR_FFT_SIZE   0x06062021   Неверно задан размер БПФ. Размер БПФ может быть составным вида (n = n_0 times n_1 times n_2 ldots times n_p times m), где (n_i = 2,3,5,7), а (m ) – произвольный простой множитель не превосходящий 46340. Ошибка возникает, когда множитель (m ) превосходит 46340. Подробнее…   #define  ERROR_FILTER_A0   0x06090100   Параметр (a_0) передаточной характеристики (H(z)) цифрового БИХ-фильтра не может быть равен нулю. Подробнее…   #define  ERROR_FILTER_APPROX   0x06090116   Неизвестный тип аппроксимации цифрового или аналогового фильтра. Данная ошибка возникает при неверном задании масок типа цифрового БИХ-фильтра. Библиотека поддерживает следущие аппроксимации: Баттерворта, Чебышева первого рода, Чебышева второго рода и эллиптические. Подробнее…   #define  ERROR_FILTER_FT   0x06090620   Неверно заданы частоты преобразования ФНЧ-ПФ и ФНЧ-РФ. Частотные маски полосовых и режекторных фильтров имеют две частоты среза или частоты заграждения. При реализации частотных преобразований фильтров необходимо задавать левую частоту среза меньше правой.
Подробнее…   #define  ERROR_FILTER_ORD   0x06091518   Порядок фильтра задан неверно. Порядок фильтра должен быть задан положительным целым значением. Подробнее…   #define  ERROR_FILTER_ORD_BP   0x06091519   Порядок полосового или режекторного фильтра задан неверно. Порядок полосового и режекторного фильтра должен быть задан чётным положительным значением. Подробнее…   #define  ERROR_FILTER_RP   0x06091816   Параметр неравномерности фильтра в полосе пропускания задан неверно. Данный параметр задается в дБ и должен быть положительным числом. Подробнее…   #define  ERROR_FILTER_RS   0x06091819   Параметр подавления фильтра в полосе заграждения задан неверно. Данный параметр задается в дБ и должен быть положительным числом. Подробнее…   #define  ERROR_FILTER_TYPE   0x06092025   Неизвестный тип фильтра. Библиотека поддерживает следущие типы фильтров: ФНЧ, ФВЧ, полосовой и режекторный. Подробнее…   #define  ERROR_FILTER_WP   0x06092316   Параметр частоты среза фильтра задан неверно. Частота среза фильтра должна быть положительной от 0 до 1 для цифрового КИХ-фильтра. Подробнее…   #define  ERROR_FILTER_WS   0x06092319   Параметр частоты заграждения фильтра задан неверно. Частота заграждения должна быть положительным числом от 0 до 1. Подробнее…   #define  ERROR_FNAME   0x06140113   Ошибка в имени файла. Необходимо задать корректное имя файла. Подробнее…   #define  ERROR_FOPEN   0x06151605   Ошибка открытия файла. Файл с заданным именем не может быть открыт для записи и (или) чтения. Подробнее…   #define  ERROR_FREAD_SIZE   0x06180501   Ошибка чтения блока данных из бинарного файла. Ошибка возникает, если при чтении блока данных из файла размер считанного блока не соответствует требуемому значению. Подробнее…   #define  ERROR_FWRITE_SIZE   0x06231820   Ошибка записи блока данных в бинарный файла. Ошибка возникает, если при записи блока данных в файл, размер записанного блока не соответствует требуемому значению. Подробнее…   #define  ERROR_GNUPLOT_CREATE   0x07161203   Невозможно подключиться к пакету GNUPLOT. Пожалуйста проверьте, что пакет доступен. Подробнее…   #define  ERROR_GNUPLOT_TERM   0x07161220   Неизвестный параметра вызова программы, задающий терминал GNUPLOT.
Данный параметр может принимать одно из следюущих значений:
--noplot построение графика не производиться;
--plotwin построение графиков производиться в отельном окне (окнах);
--plotpng построение графиков производиться в png — файл.
. Подробнее…   #define  ERROR_LAPACK   0x12011601   Встроенная функция пакета LAPACK вернула код ошибки. Данная ошибка возвращается функцией, если она использует одну из встроенных функций LAPACK, которая завершилась с ошибкой. Подробнее…   #define  ERROR_MALLOC   0x13011212   Ошибка динамического выделения памяти. Данная ошибка означает, что при динамическом выделении памяти произошла ошбика. В результате функция malloc в теле вызваемой функции вернула NULL указатель. Дальнейшая обработка функцией невозможна. Подробнее…   #define  ERROR_MATRIX_SIZE   0x13011926   Неверный размер матрицы. Подробнее…   #define  ERROR_MIN_MAX   0x13091413   Минимальное значение (нижняя граница) больше максимального. Подробнее…   #define  ERROR_NEGATIVE   0x14050701   Отрицательный параметр. Функция возвращает данный код ошибки, когда принимает отрицательный параметр в переменную, которая не может быть отрицательной. Подробнее…   #define  ERROR_POLY_AN   0x16150114   Неверно задан старший коэффициент полинома. Например при вычислении кореней полинома степени (N). Подробнее…   #define  ERROR_POLY_ORD   0x16151518   Неверно задан порядок полинома. Порядок полинома должен быть положительным целым числом. Подробнее…   #define  ERROR_PTR   0x16201800   Ошибка указателя. Данная ошибка означает, что один из обязательных указателей (память под который должна быть выделена) передан как NULL. При возникновении данной ошибки, функция завершает работу и возвращает данный код ошибки. Подробнее…   #define  ERROR_RAND_SIGMA   0x18011909   Неверно задано среднеквадратическое отклонение нормального распределения случайной величины. Среднеквадратическое отклонение должно быть неотрицательным вещественным числом. Подробнее…   #define  ERROR_RAND_TYPE   0x18012009   Неизвестный датчик псевдослучайных чисел. В библиотеке используются следующие датчики: Подробнее…   #define  ERROR_RESAMPLE_RATIO   0x18051801   Коэффициент передискретизации задан неверно. Коэффициент передискретизации задается отношением (frac{P}{Q}), где (P) и (Q) вещественные положительные числа. Подробнее…   #define  ERROR_RESAMPLE_FRAC_DELAY   0x18050604   Неверное значение дробной задержки. Дробная задержка может принимать значения от -1 до 1, где 1 соответствует одному интервалу дискретизации (1/F_{textrm{s}}). Подробнее…   #define  ERROR_SIZE   0x19092605   Ошибка при передаче размера массива. Данная ошибка возникает когда помимо указателя на массив входных или выходных данных передается неверный размер массива (меньше или равный нулю). При возникновении данной ошибки, функция завершает работу и возвращает данный код ошибки. Подробнее…   #define  ERROR_SYM_TYPE   0x19251320   Ошибка параметра типа заполнения массивов в линейном или логарифмическом масштабе. Допустимые типы заполнения: симметричный и периодический. Подробнее…   #define  ERROR_UNWRAP   0x21142318   Ошибка параметров функции раскрытия периодичности. Параметр периода и отступа должны быть положительными числами. Подробнее…   #define  ERROR_WIN_PARAM   0x23091601   Ошибка значения параметра оконной функции. Для каждой параметрической оконной функции существуют допустимые значения параметра. Подробнее…   #define  ERROR_WIN_SYM   0x23091925   Симметричность или периодичность заданного окна не поддерживается. Подробнее…   #define  ERROR_WIN_TYPE   0x23092025   Неизвестный тип оконной функции. Подробнее…  

В данной группе приведены возможные коды ошибок, возвращаемые функциями библиотеки в процессе работы.

#define ERROR_FFT_SIZE   0x06062021

Неверно задан размер БПФ. Размер БПФ может быть составным вида (n = n_0 times n_1 times n_2 ldots times n_p times m), где (n_i = 2,3,5,7), а (m ) – произвольный простой множитель не превосходящий 46340. Ошибка возникает, когда множитель (m ) превосходит 46340.

См. определение в файле dspl.h строка 571

platinum133

5 / 5 / 1

Регистрация: 19.04.2017

Сообщений: 35

1

Ошибка при вызове функции

16.05.2017, 11:06. Показов 2601. Ответов 9

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Добрый день!
Есть функция по расчету детерминанта

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int _det(int size,double **arr,double &det)
{
int i,j,k;
det=1;
double b;
for(i=0;i<size;i++)
{
    for(j=i+1;j<size;j++)
    {
    if(arr[i][i]==0)
    {
        if(arr[i][j]==0)
        b=0;
        else
        return 0;
    }
    else b=arr[j][i]/arr[i][i];
    for(k=i;k<size;k++)
    arr[j][k]=arr[j][k]-arr[i][k]*b;
    }
det*=arr[i][i];
}
return 1;
}

Работает правильно.
Ошибка при ее вызове в данном цикле, если кратко — в матрице заменяется столбец из другой матрицы и считается детерминант, далее заменяется уже второй столбец и так до конца.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
double *z = new double[size];
       for (int j=0; j<size; j++)
       {
          for (int i=0; i<size; i++) {
          z[i] = arr_x[i][j];
          arr_x[i][j] = arr_y[i];
       }
        double det;
         if(_det(size,arr_x,det)==1)
           {
             cout << "Детерминанты матрицы Xi = " << det <<endl;
           }
            else
            {
              cout << "Ошибка! Детерминант невозможно рассчитать!" << endl;
             }
               cout <<endl;
          for (int i=0; i<size; i++)
          arr_x[i][j] = z[i];
      }

При том результат верный только для первой замены, после считает неправильно, как я понимаю переменной det присваивается значение предыдущего расчета и из-за этого происходит неверный расчет.
Как исправить?



0



3434 / 2813 / 1249

Регистрация: 29.01.2016

Сообщений: 9,426

16.05.2017, 14:07

2

Цитата
Сообщение от platinum133
Посмотреть сообщение

Ошибка при ее вызове в данном цикле

Какая ошибка?



0



5 / 5 / 1

Регистрация: 19.04.2017

Сообщений: 35

16.05.2017, 14:26

 [ТС]

3

В расчетах, правильный детерминант получается только при первом вызове функции в цикле, дальше идут неверные расчеты, не могу понять почему



0



nd2

3434 / 2813 / 1249

Регистрация: 29.01.2016

Сообщений: 9,426

16.05.2017, 14:52

4

Цитата
Сообщение от platinum133
Посмотреть сообщение

не могу понять почему

При каждой итерации цикла создаёшь новый det:

Цитата
Сообщение от platinum133
Посмотреть сообщение

C++
1
double det;

Добавлено через 2 минуты
Я так и не понял: нужно сохранять значение det, изменённое в функции, или нет?

Добавлено через 4 минуты
Хотя, в любом случае, в функции, det задаётся начальное значение равное 1.

Добавлено через 2 минуты

Цитата
Сообщение от platinum133
Посмотреть сообщение

как я понимаю переменной det присваивается значение предыдущего расчета

Нет.



0



5 / 5 / 1

Регистрация: 19.04.2017

Сообщений: 35

16.05.2017, 14:53

 [ТС]

5

Сейчас напишу максимально подробно и точно. Имеем матрицу X и Y ( см. приложение). Находим функцией детерминант det_x, далее циклом заменяются столбцы ( пример во вложении), и выполняется функция. Сам временный det_xi сохранять ну нужно, сохраняется только переменная C, формула которой во вложении.

Миниатюры

Ошибка при вызове функции
 



0



3434 / 2813 / 1249

Регистрация: 29.01.2016

Сообщений: 9,426

16.05.2017, 14:54

6

Цитата
Сообщение от platinum133
Посмотреть сообщение

как я понимаю переменной det присваивается значение предыдущего расчета

Нет. Если есть ошибка, то не от этого. На каждой итерации у тебя создаётся новый det, передаётся в функцию по ссылке, там задаётся начальное значение det равное 1, потом считается, после выхода из функции выводится подсчитанное в функции значение det. И так на каждой итерации цикла.



0



5 / 5 / 1

Регистрация: 19.04.2017

Сообщений: 35

16.05.2017, 14:57

 [ТС]

7

Я вот и не понимаю, почему последующие результаты неправильные, ведь в функции det всегда задается начальное значение 1.



0



3434 / 2813 / 1249

Регистрация: 29.01.2016

Сообщений: 9,426

16.05.2017, 15:02

8

Цитата
Сообщение от platinum133
Посмотреть сообщение

Я вот и не понимаю, почему последующие результаты неправильные, ведь в функции det всегда задается начальное значение 1.

Значит дело не в det.

Цитата
Сообщение от nd2
Посмотреть сообщение

Если есть ошибка, то не от этого.



0



platinum133

5 / 5 / 1

Регистрация: 19.04.2017

Сообщений: 35

16.05.2017, 15:18

 [ТС]

9

А в чем может быть?
Если выполнить функцию до цикла с заменой столбцов для матрицы Х, детерминант посчитается правильно.

C++
1
2
3
4
5
6
7
8
9
double det_x;
          if(_det(size,arr_x,det_x)==1)
           {
             cout << "Детерминанты матрицы X = " << det_x <<endl;
           }
            else
            {
              cout << "Ошибка! Детерминант невозможно рассчитать!" << endl;
             }

Но в цикле уже и первый результат будет неверным.



0



nd2

3434 / 2813 / 1249

Регистрация: 29.01.2016

Сообщений: 9,426

16.05.2017, 17:20

10

Лучший ответ Сообщение было отмечено platinum133 как решение

Решение

Цитата
Сообщение от platinum133
Посмотреть сообщение

Если выполнить функцию до цикла с заменой столбцов для матрицы Х, детерминант посчитается правильно.

Цитата
Сообщение от platinum133
Посмотреть сообщение

Но в цикле уже и первый результат будет неверным.

Смотри, что в цикле, до вызова функции (и после), делается, а что не в цикле не делается (или не так делается).

Добавлено через 1 час 33 минуты
У тебя ошибка в том, что массив arr_x полностью не восстанавливается после вызова функции в цикле (в функции он меняется). Тебе нужно, перед циклом, сделать копию arr_x, в конце итерации цикла воостановить arr_x из копии.

Добавлено через 18 минут

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
int _det(int size, double **arr, double &det)
{
    int i , j, k;
    det = 1;
    double b;
    for (i = 0; i < size; i++)
    {
        for (j = i + 1; j < size; j++)
        {
            if (arr[i][i] == 0)
            {
                if (arr[i][j] == 0)
                    b = 0;
                else
                    return 0;
            }
            else 
                b = arr[j][i] / arr[i][i];
            for (k = i; k < size; k++)
                arr[j][k] = arr[j][k] - arr[i][k] * b;
        }
        det *= arr[i][i];
    }
    return 1;
}
 
void show(double** arr, int size)
{
    for (int i = 0; i < size; ++i)
    {
        for (int j = 0; j < size; ++j)
           cout << arr[i][j] << ' ';
        cout << endl;
    }
    cout << endl;
}
 
int main()
{   
    setlocale(0, "");
    int size = 3;
    double** arr_x = new double*[size];
    for (int i = 0; i < size; ++i)
    {
        arr_x[i] = new double[size];
        for (int j = 0; j < size; ++j)
            arr_x[i][j] = 1;
 
    }
    arr_x[0][1] = 4;
    arr_x[1][1] = 5;
    arr_x[2][1] = 55;
    arr_x[0][2] = 3;
    arr_x[1][2] = 6;
    arr_x[2][2] = 1;
    
    show(arr_x, size);
    
    double* arr_y = new double[size];
    double n = 5;
    for (int j = 0; j < size; ++j)
            arr_y[j] = n++;
    
    double **z = new double*[size];
    for (int i = 0; i < size; ++i)
        z[i] = new double[size];
 
    for (int i = 0; i < size; ++i)
        for (int j = 0; j < size; j++) 
            z[i][j] = arr_x[i][j];
        
    for (int j = 0; j < size; j++)
    {
        for (int i = 0; i < size; i++) 
        {
            arr_x[i][j] = arr_y[i];
        }
        show(arr_x, size);
        double det;
        if(_det(size,arr_x,det) == 1)
        {
            cout << "Детерминанты матрицы Xi = " << det <<endl;
        }
        else
        {
            cout << "Ошибка! Детерминант невозможно рассчитать!" << endl;
            }
            cout <<endl;
            for (int i = 0; i < size; i++)
                for (int j = 0; j < size; ++j)
                    arr_x[i][j] = z[i][j];
            show(arr_x, size);
    }
    system("pause");
}

Миниатюры

Ошибка при вызове функции
 



1



Видимо, это методы класса, поэтому я опишу класс Test с этими методами:

class Test:
  def a(self):
    self.a = "lol"

  def b(self):
    print(self.a)

Попробуем вызвать b как метод класса:

Test.b()

Вывод:

TypeError: b() missing 1 required positional argument: 'self'

Поскольку у методов a и у b есть параметр self, их правильно вызывать не от класса, а от экземпляра класса, тогда параметр self передастся автоматически:

t = Test()
t.a()
t.b()

Вывод:

lol

Однако, в вашем коде есть ещё одна проблема, попробуем вызвать метода a два раза подряд:

t = Test()
t.a()
t.a()

Вывод:

TypeError: 'str' object is not callable

Дело в том, что вас есть функция Test.a, однако в экземпляре этого класса вы когда делаете в методе a присваивание self.a = "lol", вы таким образом затираете ссылку на функцию a строкой lol. Python хранит все имена вместе, ему всё-равно что это — переменная или функция. Под одним именем может быть только одна какая-то сущность, вне зависимости от того, как эта сущность используется. Так что не делайте у методов и полей класса одинаковые названия, чтобы они друг-друга не затирали.

В следующей таблице описаны коды ошибок, сообщаемые компилятором, а также возможные причины и решения. Для наиболее распространенных ошибок приведены дополнительные комментарии.

Таблица 1 – Сообщения об ошибках и их коды

Код

Сообщение об ошибке

1

NEXT без FOR

Для окончания цикла NEXT нет соответствующего заголовка FOR. Количество FOR и NEXT должно совпадать

2

Синтаксическая ошибка

Оператор содержит грамматическую ошибку в написании ключево­го слова или ошибку в пунктуации, либо есть непарные скобки или другие нарушения правил синтаксиса языка Бейсик

3

RETURN без GOSUB

Для оператора возврата из подпрограммы RETURN нет соответствующего обращения к подпрограмме GOSUB

4

Нет данных

В операторе DATA нет данных. Посчитайте количество данных в операторе DATA и количество считываний из него оператором READ. Посмотрите внимательно, не поставили ли вы при перечислении данных в каком-нибудь месте точку вместо запятой

5

Неверный вызов функции

Возникает чаще всего при попытке извлечения квадратного корня из отрицательного числа или применения графических операторов без включения графического режима SCREEN. Вообще же подобное сообщение возникает при попытке вызова функции с недопусти­мым параметром

6

Переполнение

Числовая переменная или строковая константа выходят за пределы допустимого диапазона. Проверьте и измените значение в случае необходимости

7

Не хватает памяти

8

Метка не определена

Оператор GOTO или GOSUB пытаются осуществить переход на несу­ществующую метку

9

Индекс вне режима

Сообщение возникает при работе «с массивами, когда индекс како­го-либо элемента массива превышает его объявленный в операторе DIM размер, а также в том случае, когда массив занимает в памяти объем более 64 Кбайт

10

Повторяющееся определение

11

Деление на ноль

Выражение в знаменателе после подстановки соответствующих переменных и вычислений, видимо, обращается в ноль

12

Ошибка в режиме управления

13

Ошибка ввода

14

В строке нет места

16

Слишком сложная строковая формула

17

Невозможно продолжить

18

Функция не определена

Возможно, используемая функция не определена оператором DEF FN, или допущена ошибка при определении или вызове функции

19

Нет RESUME

20

RESUME без ошибки

24

Устройство в тайм-ауте

25

Ошибка устройства

26

FOR без NEXT

Для заголовка цикла FOR нет соответствующего окончания цикла NEXT. Количество FOR и NEXT должно совпадать

21

Нет бумаги

29

WHILE без WEND

Для ключевого слова WHILE нет соответствующего слова WEND

30

WEND без WHILE

Для ключевого слова WEND нет соответствующего слова WHILE

33

Повторяющаяся метка

При расстановке меток допущен повтор одной и той же метки в разных местах программы

35

Подпрограмма не определена

Сообщение возникает при попытке обращения к несуществующей подпрограмме

37

Ошибка счетчика аргументов

38

Массив не определен

Попытка работать с элементами массива, который не был объявлен оператором DIM

40

Необходима переменная

50

Переполнение FIELD

51

Внутренняя ошибка

Чаще всего неверная работа компьютера, реже — смысловые ошибки программы, не сразу различимые на первый взгляд. Часто требуется ручная прокрутка программы

52

Плохое имя файла/плохой номер

Имя файла не соответствует требованиям DOS

53

Файл не найден

При попытке обращения к файлу указано неправильное его имя или путь к нему

54

Плохой режим файла

55

Файл уже открыт

Попытка повторного открытия файла или удаления открытого файла

56

Оператор FIELD активен

57

Ошибка в/вв устройства

Ошибка устройства ввода/вывода, с которой не справляется DOS

Попробуйте посмотреть, все ли в порядке с аппаратной частью, т. е. внешними устройствами компьютера

58

Файл уже существует

Попытка сохранить файл под именем уже существующего на диске файла

59

Неверная длина записи

61

Диск заполнен

Диск, на который производится запись файла, не имеет достаточно места для этого. Надо освободить дисковое пространство, удалив что-нибудь менее важное

62

Ошибка: введен конец файла

63

Неверный номер записи

64

Плохое имя файла

Имя файла не соответствует требованиям DOS

67

Слишком много файлов

68

Устройство недоступно

В дисководе нет диска или он испорчен

69

Переполнение буфера коммуникации

Попытка копирования в буфер слишком большого обьема инфор­мации

70

Нет разрешения

71

Ошибка формата диска

В дисководе нет диска или он испорчен

72

Ошибка диска

В дисководе нет диска или он испорчен

73

Недоступная возможность

74

Переименование через диски

75

Ошибка доступа к пути/файлу

76

Путь не найден

При попытке обращения к файлу указано неправильное его имя или путь к нему

Опубликовано: 10 августа 2017

Исправлено: 10 августа 2017

Версия документа: 1.0

Когда ты вызываешь функцию Windows, она проверяет переданные ей параметры, а затем пытается выполнить свою работу. Если ты передал недопустимый параметр или если данную операцию нельзя выполнить по какой‐то другой причине, она возвращает значение, свидетельствующее об ошибке.

Типы данных для возвращаемых значений

Большинство функций Windows возвращают следующие типы:

Процедуры:
Подпрограммы‐процедуры Sub не возвращают значений. Такие функции всегда (или почти всегда) выполняется успешно, хотя их количество в Windows очень мало. Пример: функция ExitProcess.
BOOL или Boolean:
Если вызов функции оканчивается неудачей, то возвращается ложь False (она же 0), в остальных случаях возвращается любое другое число, отличное от нуля. Однако не пытайся сравнить это число с True, лучше просто сравнивать с нулём.
HANDLE:
Если вызов функции оканчивается неудачей, то обычно возвращается NULL, что эквивалентно нулю, в остальных случаях возвращаемое значение идентифицирует объект, которым ты можешь манипулировать. Однако некоторые функции вместо NULL в случае ошибки возвращают константу INVALID_HANDLE_VALUE, например, функция CreateFile. В документации для каждой функции чётко указано, что именно она возвращает при ошибке: NULL или INVALID_HANDLE_VALUE.
PVOID или Any Ptr:
Если вызов функции оканчивается неудачей, то возвращается NULL, в остальных случаях PVOID сообщает адрес блока данных в памяти.
HRESULT:
Если вызов функции оканчивается неудачей, то возвращается ошибочный код HRESULT, в остальных случаях значение говорит об успехе операции. Подробнее о HRESULT →
Integer, Long или DWORD:
Это значение — «крепкий орешек». Функции, которые возвращают значения каких‐либо счётчиков, обычно возвращают Integer, Long или DWORD. Если по какой‐либо причине функция не сумела сосчитать то, что ты хотел, она обычно возвращает 0 или -1, всё зависит от конкретной функции. Лучше всего проверь в документации, каким именно значением функция уведомляет об ошибке.

Почему же произошла ошибка?

При возникновении ошибки необходимо разобраться почему вызов данной функции оказался неудачен. За каждой ошибкой закреплён свой код — 32‐битное целое число.

Функция Windows, обнаружив ошибку, через механизм локальной памяти потока сопоставляет соответствующий код ошибки с вызывающим потоком. Это позволяет потокам работать независимо друг от друга, не вмешиваясь в чужие ошибки. Когда функция вернёт управление, её возвращаемое значение будет указывать на то, что произошла какая‐то ошибка. Какая именно — можно узнать, вызвав функцию GetLastError.

Declare Function GetLastError()As DWORD

Она просто возвращает числовое значение, характеризующее код ошибки.

Список кодов ошибок лежит в заголовочной файле winwinerror.bi. Здесь приведена его небольшая часть, чтобы примерно представлять, на что он похож:

Const ERROR_SUCCESS = 0
Const NO_ERROR = 0
Const ERROR_INVALID_FUNCTION = 1
Const ERROR_FILE_NOT_FOUND = 2
Const ERROR_PATH_NOT_FOUND = 3
Const ERROR_TOO_MANY_OPEN_FILES = 4
Const ERROR_ACCESS_DENIED = 5
Const ERROR_INVALID_HANDLE = 6

Функцию GetLastError необходимо вызывать сразу же после неудачного вызова функции Windows, иначе код ошибки может быть потерян.

Некоторые функции Windows всегда завершаются успешно, но по разным причинам. Например, попытка создать объект ядра «событие» с определённым именем может быть успешна потому, что оно действительно создано, либо потому, что такой объект уже существует. Но иногда нужно знать причину успеха. Для возврата этой информации корпорация Microsoft предпочла использовать механизм установки кода последней ошибки. Так что и при успешном выполнении некоторых функций ты можешь использовать GetLastError и получать дополнительную информацию. К таким функциям относится, например, CreateEvent.

Ты наверняка спросишь, составит ли корпорация Microsoft полный список всех кодов ошибок, возможных в каждой функции. Ответ: нет. Такого списка никогда не будет, уж слишком сложно его составлять и поддерживать для всё новых и новых версий системы.

Проблема с подобным списком ещё и в том, что ты вызываешь одну функцию, а она может обратиться к другой, та — к следующей и так далее. Любая из этих функций может завершиться неудачно и по самым разным причинам. Иногда функция более высокого уровня сама справляется с ошибкой в одной из вызванных ею функций, и в конечном счёте выполняет то, что от неё хотели. В общем, для создания такого списка пришлось бы проследить цепочки вызовов в каждой функции, что очень трудно. А с появлением новой версии операционной системы цепочки вызовов пришлось бы пересматривать заново.

Определение собственных кодов ошибок

Механизм установки кода ошибки можно использовать и в собственных функциях. Предположим, ты пишешь библиотечную функцию, к которой будут обращаться другие части программы или вообще другие программы. Вызов этой функции по каким‐либо причинам может оказаться неудачным и тебе придётся тоже сообщать об этом. С этой целью ты просто устанавливаешь код последней ошибки в потоке и возвращаешь значение False, INVALID_HANDLE_VALUE, NULL или что‐то другое, более подходящее в твоём случае.

SetLastError

Чтобы установить код последней ошибки вызывай функцию SetLastError и передай ей нужной число.

Declare Sub SetLastError( _
    ByVal dwErrorCode As DWORD _
)

Можно использовать коды ошибок, уже определённые в winerror.bi, если они подходят. Если ты считаешь, что ни один из кодов ошибок из winerror.bi не годится для ошибки, возможной в твоей функции, можно определить свой код.

Формат кода ошибки

Код ошибки представляет 32‐битное беззнаковое число, которое разбито на поля:

Биты числа 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Описание Степень тяжести Кем определён Зарезервировано Подсистема (facility code) Код ошибки
Биты 30 и 31:
Представляют собой степень тяжести ошибки. В двоичном виде: 00 — успех, 01 — информация, 10 — предупреждение, 11 — ошибка.
Бит 29:
Корпорация Microsoft обещала, что никогда не будет его устанавливать. Следовательно, если ты определяешь собственный код ошибки, то установи этот бит в 1 для гарантии, что твой код ошибки не будет конфликтовать с кодами, определёнными Microsoft.
Бит 28:
Зарезервирован. Должен быть 0.
Биты с 16 по 27:
Код подсистемы (facility code). Определяется корпорацией Microsoft. Указывает на компонент операционной системы, вызвавший ошибку.
Биты с 0 по 15:
Код ошибки. Определяется корпорацией Microsoft или пользователем.

Подробнее об этих полях будет рассказано в следующих статьях. На данный момент единственное важное для тебя поле — это бит 29. Чтобы гарантировать непересекаемость кодов ошибок от Microsoft, установи его в 1. В переводе на числа это означает, что твой код ошибки должен быть больше, чем &h20000000 или 536870912 в десятичном виде.

Получение описания ошибки

Для получения текстового описания ошибки подойдёт функция FormatMessage. Использовать её можно так:

#include "windows.bi"

Const BufferSize As Integer = 4096 - 1

' Строка с ошибкой
Dim ErrorMessage As WString * (BufferSize + 1) = Any

' Вызов функции с неправильным параметром
GetProcessId(NULL)

' Получить код ошибки
Dim dwError As DWORD = GetLastError()

' Получить строку по коду ошибки
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @ErrorMessage, BufferSize, NULL)

' Выводим описание ошибки на консоль
Print ErrorMessage

Понравилась статья? Поделить с друзьями:
  • Ошибка при вызове функции python
  • Ошибка при вызове функции ioctl флешка
  • Ошибка при вызове функции getcurrentstatus
  • Ошибка при вызове серверного метода
  • Ошибка при вызове операции сервиса