Форум: "Основная";
Текущий архив: 2005.10.16;
Скачать: [xml.tar.bz2];
ВнизService & DLL Найти похожие ветки
← →
HelpMy (2005-09-27 07:16) [0]При попытке из Service подключения DLL и вызова из нее процедуры появляется ошибка. Процедура в DLL подключается к базе и делает запись. Тот же самый вызов из приложения работает без проблем. Неужели Service не может работать с библиотеками? Не хотелось из Service запускать процесс.
← →
Digitman © (2005-09-27 08:21) [1]
> появляется ошибка
какая ?
← →
HelpMy (2005-09-27 08:39) [2]Это вызов из сервиса:
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;
Эту же процедуру библиотеки вызываю из Приложения, вызов слово в слово как и в сервисе, все работает.
← →
Leonid Troyanovsky © (2005-09-27 08:52) [3]
> HelpMy (27.09.05 08:39) [2]
> Эту же процедуру библиотеки вызываю из Приложения, вызов
> слово в слово как и в сервисе, все работает.
Твой сервис, очевидимо, не может TDM.Create(Application).
Такое может случиться, если у него, например,
нет прав на сетевые подключения (System, Local Service).
--
Regards, LVT.
← →
Digitman © (2005-09-27 09:09) [4]
> HelpMy (27.09.05 08:39) [2]
что у тебя происходит в конструирующем методе TDM.Create и обработчике события TDM.OnCreate ?
← →
HelpMy (2005-09-27 09:10) [5]Перед
TDM.Create(Application);
добавил:
AddToLog("Попытка выполнения");
В Log запись не происходит!!!
← →
HelpMy (2005-09-27 09:19) [6]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:27) [7]Оставил в процедуре единственную строку записи в лог файл.
AddToLog("Попытка выполнения");
Результат тот же.
Приложение без проблем, сервис гонит все ту же ошибку.
Похоже, что проблема с адресами сервиса и библиотеки.
← →
Leonid Troyanovsky © (2005-09-27 09:28) [8]
> HelpMy (27.09.05 09:10) [5]
> Перед
>
> TDM.Create(Application);
>
> добавил:
>
> AddToLog("Попытка выполнения");
>
> В Log запись не происходит!!!
Тогда сознавайся, что есть в initilization библиотечных модулей,
между begin..end. оной и т.д.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2005-09-27 09:31) [9]
> HelpMy (27.09.05 09:27) [7]
> Похоже, что проблема с адресами сервиса и библиотеки.
Пока таких проблем ты не демонстрировал.
--
Regards, LVT.
← →
Digitman © (2005-09-27 09:32) [10]соглашения о вызове точно соблюдены ?
← →
HelpMy (2005-09-27 09:53) [11]Библиотека приняла вид:
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 10:06) [12]я что-то не понял ...
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 10:53) [13]To Digitman © (27.09.05 10:06) [12]
AddToLog() присутствует и в сервисе и в библиотеке.
IsMultiThread := True нужно попробовать
← →
Digitman © (2005-09-27 11:03) [14]
> AddToLog() присутствует и в сервисе и в библиотеке
и зачем такие выкрутасы ?
организуй в коде сервиса единую процедуру протоколирования.
а еще лучше будет, если для отладки своего сервиса вместо сомнительных по надежности алгоритмов протоколирования ты воспользуешься штатными средствами штатного же встроенного отладчика Делфи
← →
HelpMy (2005-09-27 11:41) [15]To Digitman © (27.09.05 11:03) [14]
воспользуешься штатными средствами штатного же встроенного отладчика
Делфи
Проблема с отладкой DLL.
Подключить к процессу (сервису) я не успею, он при запуске сразу же обращается к DLL.
В меню RUN > Parameters... сервис будет запушен как exe.
← →
Digitman © (2005-09-27 12:06) [16]в станд.справке есть инф-ция о принципе отладки сервиса средствами встр.отладчика
> не успею
ну так поставь задержку, например, в обработчик OnStart !
← →
Digitman © (2005-09-27 12:13) [17]см. топик "Debugging service applications"
+ используй для отлад.целей вставку оператора, осуществляющего задержку, достаточную по времени для того чтобы ты успел приаттачиться к процессу сервиса
← →
Digitman © (2005-09-27 12:15) [18]+ сервисы имеют ВСТРОЕННЫЙ механизм (и его API) для протоколирования работы сервиса
см. LogMessage method (TService)
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.10.16;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.041 c