Форум: "Основная";
Текущий архив: 2010.03.28;
Скачать: [xml.tar.bz2];
ВнизОсобенности при работе с 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;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.004 c