![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Service & DLL
HelpMy © (2005-09-27 07:16:00)При попытке из Service подключения DLL и вызова из нее процедуры появляется ошибка. Процедура в DLL подключается к базе и делает запись. Тот же самый вызов из приложения работает без проблем. Неужели Service не может работать с библиотеками? Не хотелось из Service запускать процесс.
Digitman (2005-09-27 12:15:00) [1]+ сервисы имеют ВСТРОЕННЫЙ механизм (и его API) для протоколирования работы сервиса
см. LogMessage method (TService)
Digitman (2005-09-27 12:13:00) [2]см. топик "Debugging service applications"
+ используй для отлад.целей вставку оператора, осуществляющего задержку, достаточную по времени для того чтобы ты успел приаттачиться к процессу сервиса
Digitman (2005-09-27 12:06:00) [3]в станд.справке есть инф-ция о принципе отладки сервиса средствами встр.отладчика
> не успею
ну так поставь задержку, например, в обработчик OnStart !
HelpMy (2005-09-27 11:41:00) [4]To Digitman © (27.09.05 11:03) [14]
воспользуешься штатными средствами штатного же встроенного отладчика
Делфи
Проблема с отладкой DLL.
Подключить к процессу (сервису) я не успею, он при запуске сразу же обращается к DLL.
В меню RUN > Parameters... сервис будет запушен как exe.
Digitman (2005-09-27 11:03:00) [5]
> AddToLog() присутствует и в сервисе и в библиотеке
и зачем такие выкрутасы ?
организуй в коде сервиса единуюпроцедуру протоколирования.
а еще лучше будет, если для отладки своего сервиса вместо сомнительных по надежности алгоритмов протоколирования ты воспользуешься штатными средствами штатного же встроенного отладчика Делфи
HelpMy (2005-09-27 10:53:00) [6]To Digitman © (27.09.05 10:06) [12]
AddToLog() присутствует и в сервисе и в библиотеке.
IsMultiThread := True нужно попробовать
Digitman (2005-09-27 10:06:00) [7]я что-то не понял ...
procedure TLabServ.ServiceExecute(Sender: TService);
begin
AddToLog('ServiceExecute');
try
..
откуда тут взялась AddToLog(), если она объявлена и реализована в библиотеке, которую ты еще НЕ загрузил на этот момент ?
или у тебя есть ЕЩЕ одна AddToLog(), к библиотеке отношения не имеющая
> exports RegistrInDB;
> begin
> IsMultiThread := True;//важно , потому что сервис будет вызывать ф-ции библ-ки в доп.потоке !
while not Terminated do
ServiceThread.ProcessRequests( True); // пока у тебя сервис более ничем не занят (регистрация уже выполнена ранее по тексту), лучше всего будет крутиться в цикле с ожиданиемконтроллеров
HelpMy (2005-09-27 09:53:00) [8]Библиотека приняла вид:
library Shlproc;
uses
SysUtils,
Classes;
const Log = 'c:\log.txt';
var
F: TextFile;
procedure AddToLog(S: String);
begin
AssignFile(F, Log);
Append(F);
Writeln(F, 'Shlproc ' + TimeToStr(Time) + ' ' + S);
CloseFile(F);
end;
procedure RegistrInDB(Flag: byte);
begin
AddToLog('Попытка выполнения');
end;
exports RegistrInDB;
begin
end.
Рестрироваться пытаюсь при запуске сервиса
procedure TLabServ.ServiceExecute(Sender: TService);
begin
AddToLog('ServiceExecute');
try
RegisterPC(0);
AddToLog('Регистрация 0');
except
on E: Exception do
begin
AddToLog(E.ClassName + ' ' + e.Message);
end;
end;
while Runing do
Sleep(10);
ServiceThread.ProcessRequests(False); {}
AddToLog('ServiceExecute успешно');
end;
RegisterPC(0);приведен в
HelpMy (27.09.05 08:39) [2]
То Digitman © (27.09.05 09:32) [10]
соглашения о вызове точно соблюдены ?
... можно уточнить?
Digitman (2005-09-27 09:32:00) [9]соглашения о вызове точно соблюдены ?
Leonid Troyanovsky (2005-09-27 09:31:00) [10]
> HelpMy (27.09.05 09:27) [7]
> Похоже, что проблема с адресами сервиса и библиотеки.
Пока таких проблем ты не демонстрировал.
--
Regards, LVT.
Leonid Troyanovsky (2005-09-27 09:28:00) [11]
> HelpMy (27.09.05 09:10) [5]
> Перед
>
> TDM.Create(Application);
>
> добавил:
>
> AddToLog('Попытка выполнения');
>
> В Log запись не происходит!!!
Тогда сознавайся, что есть в initilization библиотечных модулей,
между begin..end. оной и т.д.
--
Regards, LVT.
HelpMy (2005-09-27 09:27:00) [12]Оставил в процедуре единственную строку записи в лог файл.
AddToLog('Попытка выполнения');
Результат тот же.
Приложение без проблем, сервис гонит все ту же ошибку.
Похоже, что проблема с адресами сервиса и библиотеки.
HelpMy (2005-09-27 09:19:00) [13]TO Digitman © (27.09.05 09:09) [4]
TDM.Create и TDM.OnCreate ни как не используются.
Это модуль данных, в который помещены компоненты
TIBDatabase, TIBSQL, TIBTransaction.
Ниже значимая часть dfm:
object Query: TIBSQL
Database = Base
ParamCheck = True
Transaction = Tr
Left = 120
Top = 16
end
object Tr: TIBTransaction
Active = False
DefaultDatabase = Base
end
object Base: TIBDatabase
DatabaseName = 'localhost:test'
Params.Strings = (
'user_name=sysdba'
'password=masterkey'
'lc_ctype=WIN1251')
LoginPrompt = False
DefaultTransaction = Tr
SQLDialect = 3
end
Судя по HelpMy (27.09.05 09:10) [5]
Ошибка происходит до создания DM.
HelpMy (2005-09-27 09:10:00) [14]Перед
TDM.Create(Application);
добавил:
AddToLog('Попытка выполнения');
В Log запись не происходит!!!
Digitman (2005-09-27 09:09:00) [15]
> HelpMy (27.09.05 08:39) [2]
что у тебя происходит в конструирующем методе TDM.Create и обработчике события TDM.OnCreate ?
Leonid Troyanovsky (2005-09-27 08:52:00) [16]
> HelpMy (27.09.05 08:39) [2]
> Эту же процедуру библиотеки вызываю из Приложения, вызов
> слово в слово как и в сервисе, все работает.
Твой сервис, очевидимо, не может TDM.Create(Application).
Такое может случиться, если у него, например,
нет прав на сетевые подключения (System, Local Service).
--
Regards, LVT.
HelpMy (2005-09-27 08:39:00) [17]Это вызов из сервиса:
procedure TLabServ.RegisterPC(Flag: byte);
type
TLibProc = procedure(Flag: byte);
var
LibHandle: THandle;
LibProc: TLibProc;
const LibName = 'Shlproc.dll';
ProcName = 'RegistrInDB';
begin
LibHandle := LoadLibrary(LibName);
AddToLog('Регистрация');
if LibHandle <> 0 then
begin
try
try
@LibProc := GetProcAddress(LibHandle, ProcName);
AddToLog('Адрес процедуры ' + IntToStr(Integer(@LibProc)));
if @LibProc <> nil
then LibProc(Flag)
else AddToLog('Не удалось найти функцию ' + ProcName);
finally
FreeLibrary(LibHandle);
end;
except
on E: Exception do AddToLog(E.ClassName + ' ' + e.Message);
end;
end
else AddToLog('Не удалось найти библиотеку ' + LibName);
end;
Это запись в Log, при вызове:
8:24:06 Регистрация
8:24:06 Адрес процедуры 17744456
8:24:07 EAccessViolation Access violation at address 00403D42 in module 'Serv.exe'. Read of address 011355D0
Это сама процедура в библиотеке:
procedure RegistrInDB(Flag: byte);
begin
DM := TDM.Create(Application);
try
try
DM.Base.Open;
if not DM.Base.Connected then begin
AddToLog('База недоступна');
Exit;
end
else AddToLog('Подключение успешно');
DM.Query.SQL.Text := 'EXECUTE PROCEDURE REGISTER(:PC_NAME, :FLAG)';
DM.Tr.StartTransaction;
DM.Query.Params[0].AsString := 'QWERTY';
DM.Query.Params[1].AsInteger := 0;
DM.Query.ExecQuery;
DM.Tr.Commit
except
on E: Exception do
begin
AddToLog(E.ClassName + ' ' + e.Message);
DM.Tr.Rollback;
DM.Base.Close;
end;
end;
finally
DM.Free;
end;
end;
Эту же процедуру библиотеки вызываю из Приложения, вызов слово в слово как и в сервисе, все работает.
Digitman (2005-09-27 08:21:00) [18]
> появляется ошибка
какая ?