Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Перестал работать ранее рабочий код / 21 сообщений из 21, страница 1 из 1
20.12.2019, 10:01
    #39905955
LiYing
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
Delphi XE, win 7x64. Прекрасно работающий несколько лет назад код, вдруг стал выдавать AV
Project xxx.exe raised exception class EAccessViolation with message 'Access violation at address 00409230 in module 'xxx.exe'. Read of address CC8B1287'.
Сокращенный до воспроизводимого минимума код:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
function GetNumForNextInstance: string;
var
  il: TList<Integer>;

  function EnumProc(h: HWND; Param: LongInt): Boolean; stdcall;
  begin
    il.Add(1); // AV here!
  end;

begin
  il := TList<Integer>.Create;
  try
    il.Add(0); // OK
    EnumWindows(@EnumProc, 0);
  finally
    il.Free;
  end;
end;


Что не так?
Скрин с callstack:
...
Рейтинг: 0 / 0
20.12.2019, 10:16
    #39905966
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
LiYing,

А так?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
function EnumProc(h: HWND; Param: LPARAM): Boolean; stdcall;
var
  il: TList<Integer> absolute Param;
begin
  il.Add(1); 
end;

function GetNumForNextInstance: string;
var
  il: TList<Integer>;
begin
  il := TList<Integer>.Create;
  try
    il.Add(0); // OK
    EnumWindows(@EnumProc, LPARAM(il));
  finally
    il.Free;
  end;
end;


Завязывайте уже с локальными коллбэками, да ещё и с обращением к внешним переменным.
...
Рейтинг: 0 / 0
20.12.2019, 10:34
    #39905978
LiYing
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
alekcvp
А так?

Так работает, спасибо!
Завязываю... :)
...
Рейтинг: 0 / 0
20.12.2019, 10:37
    #39905980
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
Странно, что вообще давал такое провернуть.
...
Рейтинг: 0 / 0
20.12.2019, 10:43
    #39905987
LiYing
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
Василий 2
Странно, что вообще давал такое провернуть.

Чесслово, работало! На этом же компе, с этой же виндой и делфи. Проект тот не компилил года 2-3, а тут достал внести маленькое изменение, а оно AV стало выдавать... может обнова винды какая сыграла роль, ибо все остальное осталось прежним.. ну да ладно, переделаю уже "по-взрослому" :)
...
Рейтинг: 0 / 0
20.12.2019, 10:58
    #39905997
ёёёёё
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
LiYing
Чесслово, работало!

Небось, с глобальными объектами работала enum процедурка, или в контексте объекта, адрес которой передавался во втором параметре, а ты в лоб локальный добавил, или вообще поле объекта.
...
Рейтинг: 0 / 0
20.12.2019, 11:02
    #39906001
LiYing
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
ёёёёё,

да нет же! Просто попытался скомпилировать старый проект, ранее 100% рабочий, а тут AV... ничего не менял вообще.
...
Рейтинг: 0 / 0
20.12.2019, 11:17
    #39906012
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
ёёёёё
LiYing
Чесслово, работало!

Небось, с глобальными объектами работала enum процедурка, или в контексте объекта, адрес которой передавался во втором параметре, а ты в лоб локальный добавил, или вообще поле объекта.

В тот раз просто так регистры сошлись... а в этот не сошлись
Тут гулял по инету модуль Base64, где автор в ассемблерной процедуре вместо EDX считывал второй параметр из EBX - и ничего, в 9 их 10 случае работало... почему-то :)
...
Рейтинг: 0 / 0
20.12.2019, 13:29
    #39906107
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
...
Рейтинг: 0 / 0
20.12.2019, 13:40
    #39906116
LiYing
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
GunSmoker,

Вот спасибо, очень познавательно!
...
Рейтинг: 0 / 0
20.12.2019, 15:36
    #39906201
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
LiYing,

Не используйте операцию взятия адреса от функции/метода и компилятор не даст вам писать лажу
...
Рейтинг: 0 / 0
20.12.2019, 17:08
    #39906259
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
_Vasilisk_
LiYing,

Не используйте операцию взятия адреса от функции/метода и компилятор не даст вам писать лажу

А как еще winapi вызывать?
...
Рейтинг: 0 / 0
20.12.2019, 21:10
    #39906382
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
Василий 2
А как еще winapi вызывать?
Вот такой код
Код: pascal
1.
2.
3.
function EnumProc(h: HWND; Param: LPARAM): BOOL; stdcall;
.......
EnumWindows(EnumProc, 0);

замечательно работает.

И даже такой

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
TMyClass = class
  class function EnumProc(h: HWND; Param: LPARAM): BOOL; stdcall; static;
  procedure Enum;
end;
.......
procedure TMyClass.Enum;
begin
  EnumWindows(EnumProc, 0);
end;
...
Рейтинг: 0 / 0
20.12.2019, 22:01
    #39906398
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
_Vasilisk_, у тебя что за заголовочники? Просто в Delphi RTL объявлено так:
Код: pascal
1.
2.
3.
TFarProc = Pointer;
TFNWndEnumProc = TFarProc;
function EnumWindows(lpEnumFunc: TFNWndEnumProc; lParam: LPARAM): BOOL; stdcall;
...
Рейтинг: 0 / 0
21.12.2019, 16:05
    #39906491
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
GunSmoker
у тебя что за заголовочники? Просто в Delphi RTL объявлено так:
Согласен. Конкретно с этим случаем недосмотрел. Придется таки брать указатель.

Или попробовать завести тикет в QC. Хотя мои тикеты с ошибками импорта висят уже полтора года, а тут простое удобство...
...
Рейтинг: 0 / 0
23.12.2019, 10:20
    #39906873
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
_Vasilisk_
Вот такой код
Код: pascal
1.
2.
3.
function EnumProc(h: HWND; Param: LPARAM): BOOL; stdcall;
.......
EnumWindows(EnumProc, 0);

замечательно работает.

Так подобное объявление тоже пропустит локальную функцию, разве нет?
...
Рейтинг: 0 / 0
23.12.2019, 10:36
    #39906886
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
Василий 2
_Vasilisk_
Вот такой код
Код: pascal
1.
2.
3.
function EnumProc(h: HWND; Param: LPARAM): BOOL; stdcall;
.......
EnumWindows(EnumProc, 0);

замечательно работает.

Так подобное объявление тоже пропустит локальную функцию, разве нет?

Если параметр EnumProc объявлен как процедурный тип, а не указатель, то нет.
...
Рейтинг: 0 / 0
23.12.2019, 11:54
    #39906937
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
Да, действительно. Но вряд ли это будут исправлять. Вон, попытались спрятать страшные указатели в OUT-параметрах от неофитов, заменив их на var. В итоге возможность передать туда nil без мусорной переменной затруднена, в некоторых местах без указателей все равно не обойтись, соответственно теперь два равноправных стандарта трансляции api функций, и никто не знает, какому из них следовать.
...
Рейтинг: 0 / 0
23.12.2019, 19:10
    #39907244
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
Василий 2
теперь два равноправных стандарта трансляции api функций, и никто не знает, какому из них следовать.

А ведь логично было бы параметры, допускающие nil, передавать через указатели, а обязательные - через var. И всегда было бы понятно, какие обязательные, а какие - нет. Но это ведь так сложна!
...
Рейтинг: 0 / 0
23.12.2019, 19:58
    #39907275
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
Василий 2
В итоге возможность передать туда nil без мусорной переменной затруднена
Код: pascal
1.
PInteger(nil)^
...
Рейтинг: 0 / 0
24.12.2019, 10:29
    #39907387
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перестал работать ранее рабочий код
alekcvp
Василий 2
теперь два равноправных стандарта трансляции api функций, и никто не знает, какому из них следовать.

А ведь логично было бы параметры, допускающие nil, передавать через указатели, а обязательные - через var. И всегда было бы понятно, какие обязательные, а какие - нет. Но это ведь так сложна!

Хорошая мысля приходит... как всегда
_Vasilisk_
Василий 2
В итоге возможность передать туда nil без мусорной переменной затруднена
Код: pascal
1.
PInteger(nil)^


Знаю, потому и написал, что не невозможна, а затруднена
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Перестал работать ранее рабочий код / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]