Российский производитель и разработчик сертифицированного измерительного оборудования с 1987 года


E14-140M Режим покадровой синхронизации

Вы не вошли.

 Поиск | Регистрация | Вход 

12.05.2014 10:49:30
#26

Сотрудник "Л Кард"
Здесь с 18.04.2014
Сообщений: 810

Re: E14-140M Режим покадровой синхронизации

В первом же вызове так?
Чему равно lpNumberOfBytesTransferred на выходе из GetOverlappedResult?
unidir.cpp из e140-console-test.zip работает?
Попробуйте сделать тест без потоков и без индексов, просто последовательное выполнение кода.

12.05.2014 12:03:31
#27

Участник
Здесь с 18.04.2014
Сообщений: 17

Re: E14-140M Режим покадровой синхронизации

Да, при первом же вызове. Согласно идеологии, я делаю массив из двух Overlapped структур, двух приемных массивов, создаю и назначаю сигнальные события. До старта АЦП выполняю сначала Стоп, согласно рекомендаций, затем первый асинхронный запрос, первой структурой Overlapped, потом старт АЦП, выполняю второй асинхронный запрос второй структурой, жду события из первой структуры, дожидаюсь, GetOverlappedResult дает указанную ошибку. Значение lpNumberOfBytesTransferred возвращается 0, так же как и буфер в ReadFile тоже нулевой.

unidir.cpp работает, я собственно на нее и смотрел, когда кодил. Сейчас попробую сделать без потока, но вряд ли в этом дело.

12.05.2014 12:37:40
#28

Участник
Здесь с 18.04.2014
Сообщений: 17

Re: E14-140M Режим покадровой синхронизации

procedure Test;
var hEvent  : array[0..1] of THandle;
  	ov      : array[0..1] of Overlapped;
    ReadRes : boolean;
    LastErr : cardinal;
    wasReadBytes : DWORD;
    I : integer;
    RB: cardinal;
    yRes: LongBool;
    Buf : array[0..1] of array of SHORT;
begin
	for I := 0 to 1 do
    begin
        SetLength(Buf[I], DataStep);
        ZeroMemory(Buf[I], DataStep*2);
        hEvent[I] := CreateEvent(NIL, True , False, NIL);
    end;
    if NOT pModule.STOP_ADC then exit;

    ZeroMemory(@ov[0], SizeOf(Overlapped));
    ov[0].hEvent := hEvent[0];
    ReadRes := ReadFile(MdlHandle, Buf[0], SizeOf(Buf[0]), wasReadBytes, @ov[0]);
    LastErr := GetLastError;
    if (ReadRes = False) and (LastErr <> ERROR_IO_PENDING) then
    begin
        Log('Bad 1');
    end;

    if pModule.START_ADC then
    begin
        ZeroMemory(@ov[1], SizeOf(Overlapped));
        ov[1].hEvent := hEvent[1];

        ReadRes := ReadFile(MdlHandle, Buf[1], SizeOf(Buf[1]), wasReadBytes, @ov[1]);
        LastErr := GetLastError;
        if (ReadRes = False) and (LastErr <> ERROR_IO_PENDING) then
        begin
            Log('Bad 2');
        end;

        WaitForSingleObject(ov[0].hEvent, Infinite);                   

        RB := 0;
        yRes := GetOverlappedResult(MdlHandle, ov[0], RB, True);

        if NOT yRes then
        begin
            Log(GetLastErrorText);
        end;
        if RB = 0 then ;
    end;
end;

Вот такой последовательный прогон с указанной ошибкой. Не в потоке.

12.05.2014 13:37:22
#29

Сотрудник "Л Кард"
Здесь с 18.04.2014
Сообщений: 810

Re: E14-140M Режим покадровой синхронизации

MdlHandle инициализирован?

12.05.2014 13:57:32
#30

Участник
Здесь с 18.04.2014
Сообщений: 17

Re: E14-140M Режим покадровой синхронизации

Да, ранее со всеми инициализациями MdlHandle := pModule.GetModuleHandle(); Эту часть кода я с примера вашего взял и почти не трогал. Возвращает валидное значение. Все то же с использованием ReadData работает. Скорее всего как всегда какая-нибудь глупость, но пока я ее не найду.

12.05.2014 14:04:47
#31

Участник
Здесь с 18.04.2014
Сообщений: 17

Re: E14-140M Режим покадровой синхронизации

Так, если приемный буфер объявить статическим массивом, то ошибки нет. Значит дело в ReadFile, но проявляется позднее из-за асинхронности.

12.05.2014 14:26:23
#32

Участник
Здесь с 18.04.2014
Сообщений: 17

Re: E14-140M Режим покадровой синхронизации

Не пойму как отредактировать сообщения. В общем ошибка была в том, что для динамического массива при использовании WinAPI ReadFile нужна ссылка на его начало, в данном примере Buf[ind][0], ну и правильное определение его величины в байтах для передачи в функцию.

12.05.2014 15:56:18
#33

Сотрудник "Л Кард"
Здесь с 18.04.2014
Сообщений: 810

Re: E14-140M Режим покадровой синхронизации

Ах вот что! Это специфичная для Delphi штука.
Похоже, Delphi создала Вам динамический массив со скрытыми управляющими полями или что-то подобное.
На С такого не бывает, там имя массива является указателем на нулевой элемент.