Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.03.28;
Скачать: CL | DM;

Вниз

Особенности при работе с com портом в dll.   Найти похожие ветки 

 
Дмитрий Белькевич   (2009-07-13 21:04) [0]

Использую компоненту 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-13 21:06) [1]

в этом коде зависимостей от DLL не видно :)


 
Сергей М. ©   (2009-07-13 21:52) [2]

У тебя ошибка в 17-й строке.


 
Дмитрий Белькевич   (2009-07-13 23:21) [3]

>в этом коде зависимостей от 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 23:26) [4]


> Как синхронизацию сделать ..? Есть мысль
> вообще синхронизацию убрать


Ты уж определись как-нибудь - то ли "сделать", то ли "убрать" ..
А потом уж будем рассуждать про "в dll" и про "не в dll".


 
Loginov Dmitry ©   (2009-07-13 23:59) [5]


> При создании компоненты в VCL всё нормально работает. При
> создании из dll не срабатывает Synchronize(DoEvents). Тред
> заходит в Synchronize и DoEvents не вызывается.


Проблема из-за того, что для объекта Application, созданного в DLL, не устанавливается свойство Handle. Соответственно его нужно передавать при инициализации библиотеки. Лучше использовать пакеты. Или же другую библиотеку для работы с COM-портами, не завязанную так жестко на VCL.


 
Игорь Шевченко ©   (2009-07-13 23:59) [6]

Дмитрий Белькевич   (13.07.09 23:21) [3]

А обязательно DLL ? BPL не спасет ?

Может быть (точно не уверен), что Syncronize использует глобальные переменные, которые разные для DLL и для приложения. По крайней мере в classes.pas таких глобальных переменных есть.


> Есть мысль вообще синхронизацию убрать, т.к. VCL в длл не
> используется, попробовал без неё - работает, не знаю только,
>  насколько это надёжно.


все зависит от того, что находится в DoEvents и в контексте какого потока эти DoEvents должны выполняться.


 
Германн ©   (2009-07-14 01:03) [7]


> Особенности при работе с com портом в dll. [WinXP]
>
> Дмитрий Белькевич   (13.07.09 21:04)
>
> Использую компоненту TSerialPort для работы с com портами.
>
>

Неужто так трудно не использовать компоненты, тем более сторонние, для работы с Com-портами? Тогда и не будет проблем с dll.
Вот как глянешь на Synchronize в приведённом коде, так сразу и понимаешь всю бредовость такого решения.


 
Германн ©   (2009-07-14 01:37) [8]


> тем более сторонние,

Ну я сказал!
:)
P.S. Автору.
Если хочешь могу выслать тебе книгу П. Агурова по работе с сом-портом. Прочитаешь, поможет.


 
Дмитрий Белькевич   (2009-07-14 02:02) [9]

>Неужто так трудно не использовать компоненты, тем более сторонние, для работы с Com-портами?

Отвязал от VCL, убрал Synchronize. Вроде всё работает.

>Если хочешь могу выслать тебе книгу П. Агурова по работе с сом-портом. Прочитаешь, поможет.

Спасибо, если проблемы продолжатся - обращусь.

Всем спасибо за участие...



Страницы: 1 вся ветка

Текущий архив: 2010.03.28;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.012 c
2-1264361195
Дмитрий
2010-01-24 22:26
2010.03.28
Scrollbar на panel


1-1246429266
Василий Иванов_22
2009-07-01 10:21
2010.03.28
меню в ресурсе


2-1264707676
AntiDotNet
2010-01-28 22:41
2010.03.28
Смена Hint а в трее


15-1262975426
Pitbull
2010-01-08 21:30
2010.03.28
HTML Help Workshop


15-1262773736
NewZ
2010-01-06 13:28
2010.03.28
Драйверы Windows.