![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Особенности при работе с com портом в dll. [WinXP]
Дмитрий Белькевич © (2009-07-13 21:04:00)Использую компоненту TSerialPort для работы с com портами.
Метод чтения данных из порта:
function THSerialPort.Read(var Buffer; Count: Integer): Integer;
var
Overlapped: TOverlapped;
BytesRead: DWORD;
begin
FillChar(Overlapped,SizeOf(Overlapped),0);
Overlapped.hEvent:=CreateEvent(nil,False,False,nil);
ReadFile(ComHandle,Buffer,Count,BytesRead,@Overlapped);
WaitForSingleObject(Overlapped.hEvent,INFINITE);
if not GetOverlappedResult(ComHandle,Overlapped,BytesRead,False) then DoOnError('Unable to read from port',GetLastError);
CloseHandle(Overlapped.hEvent);
Result:=BytesRead;
end;
Создаю компоненту в рантайме. При создании её в OnCreate тестовой формы всё нормально работает. Данные читаются из порта без особенностей.
Когда же создаю компоненту в dll, то данные из порта не читаются.
Дмитрий Белькевич (2009-07-14 02:02:00) [1]>Неужто так трудно не использовать компоненты, тем более сторонние, для работы с Com-портами?
Отвязал от VCL, убрал Synchronize. Вроде всё работает.
>Если хочешь могу выслать тебе книгу П. Агурова по работе с сом-портом. Прочитаешь, поможет.
Спасибо, если проблемы продолжатся - обращусь.
Всем спасибо за участие...
Германн (2009-07-14 01:37:00) [2]
> тем более сторонние,
Ну я сказал!
:)
P.S. Автору.
Если хочешь могу выслать тебе книгу П. Агурова по работе с сом-портом. Прочитаешь, поможет.
Германн (2009-07-14 01:03:00) [3]
> Особенности при работе с com портом в dll. [WinXP]
>
> Дмитрий Белькевич (13.07.09 21:04)
>
> Использую компоненту TSerialPort для работы с com портами.
>
>
Неужто так трудно не использовать компоненты, тем более сторонние, для работы с Com-портами? Тогда и не будет проблем с dll.
Вот как глянешь на Synchronize в приведённом коде, так сразу и понимаешь всю бредовость такого решения.
Loginov Dmitry (2009-07-13 23:59:00) [4]
> При создании компоненты в VCL всё нормально работает. При
> создании из dll не срабатывает Synchronize(DoEvents). Тред
> заходит в Synchronize и DoEvents не вызывается.
Проблема из-за того, что для объекта Application, созданного в DLL, не устанавливается свойство Handle. Соответственно его нужно передавать при инициализации библиотеки. Лучше использовать пакеты. Или же другую библиотеку для работы с COM-портами, не завязанную так жестко на VCL.
Игорь Шевченко (2009-07-13 23:59:00) [5]Дмитрий Белькевич (13.07.09 23:21) [3]
А обязательно DLL ? BPL не спасет ?
Может быть (точно не уверен), что Syncronize использует глобальные переменные, которые разные для DLL и для приложения. По крайней мере в classes.pas таких глобальных переменных есть.
> Есть мысль вообще синхронизацию убрать, т.к. VCL в длл не
> используется, попробовал без неё - работает, не знаю только,
> насколько это надёжно.
все зависит от того, что находится в DoEvents и в контексте какого потока эти DoEvents должны выполняться.
Сергей М. (2009-07-13 23:26:00) [6]
> Как синхронизацию сделать ..? Есть мысль
> вообще синхронизацию убрать
Ты уж определись как-нибудь - то ли "сделать", то ли "убрать" ..
А потом уж будем рассуждать про "в dll" и про "не в dll".
Дмитрий Белькевич (2009-07-13 23:21:00) [7]>в этом коде зависимостей от DLL не видно :)
Ну там кода-то моего и нет почти - компонента просто создаётся и там и там:
FHSerialPort := THSerialPort.Create(nil);
FHSerialPort.OnRxChar := ReceiveByte;
FHSerialPort.OnError := PortError;
> У тебя ошибка в 17-й строке.
Согласен, по этим данным - гадание по гуще.
Отладчиком компоненту немного пощупал. Есть новые данные...
Кроме методов чтения/записи и прочей обвязки, в компоненте создаётся тред, который обрабатывает события порта.
Вот его execute:
procedure TComThread.Execute;
var
EventHandles: Array[0..1] of THandle;
Overlapped: TOverlapped;
dwSignaled, BytesTrans: DWORD;
begin
FillChar(Overlapped,SizeOf(Overlapped),0);
Overlapped.hEvent:=CreateEvent(nil,True,True,nil);
EventHandles[0]:=StopEvent;
EventHandles[1]:=Overlapped.hEvent;
repeat
WaitCommEvent(Owner.ComHandle,Mask,@Overlapped);
dwSignaled:=WaitForMultipleObjects(2,@EventHandles,False,INFINITE);
case dwSignaled of
WAIT_OBJECT_0:Break;
WAIT_OBJECT_0+1: if GetOverlappedResult(Owner.ComHandle,Overlapped,BytesTrans,False) then Synchronize(DoEvents);
else Break;
end;
until False;
Owner.PurgeIn;
Owner.PurgeOut;
CloseHandle(Overlapped.hEvent);
CloseHandle(StopEvent);
end;
При создании компоненты в VCL всё нормально работает. При создании из dll не срабатывает Synchronize(DoEvents). Тред заходит в Synchronize и DoEvents не вызывается.
Как синхронизацию сделать в случае работы в dll? Есть мысль вообще синхронизацию убрать, т.к. VCL в длл не используется, попробовал без неё - работает, не знаю только, насколько это надёжно.
Сергей М. (2009-07-13 21:52:00) [8]У тебя ошибка в 17-й строке.
Игорь Шевченко (2009-07-13 21:06:00) [9]в этом коде зависимостей от DLL не видно :)