Главная страница
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.015 c
15-1263142666
TUser
2010-01-10 19:57
2010.03.28
Письмо про СС в России ...


2-1264342999
Делфиец
2010-01-24 17:23
2010.03.28
Как разом очистить всю таблицу


1-1245059144
webpauk
2009-06-15 13:45
2010.03.28
Ошибка перехвата FormDestroy


15-1263159025
Юрий
2010-01-11 00:30
2010.03.28
С днем рождения ! 11 января 2010 понедельник


3-1237110214
Den
2009-03-15 12:43
2010.03.28
Как узнать номер добавленной записи