Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.09.16;
Скачать: [xml.tar.bz2];

Вниз

У меня возникает ошибка при вызове процедуры из DLL внутри потока   Найти похожие ветки 

 
Kent   (2002-09-04 16:33) [0]

Привет, всем !
Прошу помощи, позарез надо решить задачу.
У меня возникает ошибка при вызове процедуры из DLL внутри потока, поток прямой наследник класса TThread, вот кусок кода:


procedure TSPDLLThread.Execute;
var FarProc: procedure (LogFileName,ResultPath,Exclusions: PChar;
UUCounting,LTCounting,DoBackup: Boolean;
BackupName: PChar; EraseLog: Boolean);
begin
OnTerminate:=Form1.ThreadDone;
FreeOnTerminate:=True;
if WaitForSingleObject(SPThreadMutex,INFINITE)=WAIT_OBJECT_0 then
begin
FDLLHandle:=LoadLibrary(PChar(FDLLName));
if FDLLHandle<>0 then
begin
@FarProc:=GetProcAddress(FDLLHandle,PChar(FFarProcName));
if @FarProc<>nil then
begin
//Вот если вызов функции FarProc не выполнять, все ОК
//Иначе Access Violation, причем если вызов выполнять
//в контексте основной программы, то все отлично
//Но процедура долгая - нужен параллельный поток
FarProс(FLogFileName,FResultPath,FExclusions,
FUUCounting,FLTCounting,FDoBackup,
FBackupName,FEraseLog);
end;
FreeLibrary(FDLLHandle);
end;
end;
ReleaseMutex(SPThreadMutex);
end;

В чем проблема - никак не доеду :( !!!!
Помогите PLS !!!!


 
NailS   (2002-09-04 17:06) [1]

А как процедура в длл объявлена?


 
Виктор Щербаков   (2002-09-04 17:11) [2]

Здесь вроде всё ОК. Наверно причина возникновеня ошибки в коде FarProc. И еще, интересно, почему отсутствует соглашение овызове в объявлении функции? Так и задумано?


 
Kent   (2002-09-04 17:21) [3]

В FarProc, когда я ее вызываю из тела основной программы, ошибок не вылезает вообще все четко, но сама процедура ведет разбор и анализ лога, довольно долгая процедура. Вот и понадобилось ее запихать в фоновый процесс с низким приоритетом, а то создается впечатление, что программа подвисла :(.

Процедура в DLL объявлена как:

procedure ParseLog(StatLogName: PChar;
ResultPath: PChar;
Excs: PChar;
UUserCount: Boolean;
LTCounting: Boolean;
DoBackup:Boolean;
BackupName: PChar;
EraseLog: Boolean);

По поводу соглашений о вызове, как говорится, поподробнее .. :), если нетрудно :), как правильней здесь поступить?


 
Виктор Щербаков   (2002-09-04 17:25) [4]


> как правильней здесь поступить

Ну это не принципиально. Главное чтобы они совпадали. Обычно пишут и там и тут stdcall


 
NailS   (2002-09-04 17:28) [5]

А мьютекс зачем?
И код процедуры в студию.


 
Kent   (2002-09-04 17:32) [6]

Да, вот еще интересный факт !!! Процедура начинает работу, в процессе выполнения там, внутри процедуры, создаются и записываются файлы, так вот файлы она создает, даже впечатление, что что-то обрабатывает... но , Access Violation at address bla-bla-bla etc...и файлы по 0 кб. Я попробую дома еще раз оттрассировать процедуру, может быть возникает ошибка при работе с файлами ... хотя если в теле программы-то делать .. не возникает. Во какая заморока ... :))


 
Kent   (2002-09-04 17:36) [7]

А мьютекс необходим для того, чтобы основная программа ждала окончания работы потока по WaitForSingleObject (чтобы не было эффекта подвисания). А то она накидывается на еще не обработанные файлы и выводит не полную информацию. Вот как !! А код какой процедуры в студию ???


 
NailS   (2002-09-04 17:47) [8]


> А то она накидывается на еще не обработанные файлы и выводит
> не полную информацию. Вот как

Хитро.

Процедуру, которая в длл файлы обрабатывает, и внутри которой ошибка происходит.


 
Digitman   (2002-09-04 18:10) [9]

>Kent

Как раз и будет этот самый "эффект подвисания" ! ты ж в осн.потоке ждешь некоторое время этот мьютекс, не реагируя никак на оконные сообщения... Тогда уж MsgWaitForMultipleObjects нужно использовать в цикле : и мьютекс дождешься и оконные сообщения обрабатывать будешь успевать)

Только мьютекс здесь лишний - для MsgWaitForMultipleObjects достаточно хэндла код.потока, завершения которого ты ожидаешь. Как только он завершится, ф-ция "просигналит" точно также, как при ожидании освобождения мьютекса


 
Kent   (2002-09-05 08:47) [10]

Да вот я тоже так думал, что будет с WaitForSingleObject "висяк", ан нет - делаю поток, пока основная прога ждет освобождения мьютекса, я свободно могу таскать ее за "шиворот", она реагирует на меню....
А мьютекс мне здесь просто удобно использовать: дело в том, что к этим файлам, которые обрабатываются одним потоком, может обратиться другой поток, формирующий на основании данных из файлов контент HTML-страницы. Вот и передается у меня мьютекс, как маркер, от одного потока к другому, чтобы они не накладывались по времени ....

А процедуру я не смогу сюда поместить - она просто здоровая очень, длинные строки, боюсь что читать будет очень сложно...


 
Kent   (2002-09-05 09:58) [11]

Похоже все таки где-то некорректно выполняются операции во внешней процедуре. Сейчас сделал тестовую библиотеку с одной функцией, которая делает строке UpperCase ... и все работает 8).
У меня уже крыша скоро съедет. Буду препарировать свой код. О результате сообщу ....
Огромное спасибо всем кто откликнулся !!!
P.S. Какое счастье иметь выделенный канал :))), хоть с братьями по разуми пообщаться не дергаясь можно . :))


 
Digitman   (2002-09-05 10:59) [12]

The WaitForSingleObject function returns when one of the following occurs:

· The specified object is in the signaled state.
· The time-out interval elapses.

А если WaitForSingleObject вызвана в осн.потоке, таймаут = INFINITE и доп.поток не освобождает долгое время мьютекс ? Каким же образом осн.поток у тебя будет обрабатывать оконные сообщения, если он в дан.момент ждет завершения ф-ции WaitForSingleObject, которая "зависла" на неопред.время ?


 
Kent   (2002-09-05 11:00) [13]

А вот и свежие блинчики !!! Нашел трабл !!!
Короче, не вдаваясь в подробности заменил все свойства метода, определенные как PChar на string. (Мне в поток надо было передать имя файла для обработки, я передавал его как PChar).
Работает !! Такое впечатление, что либо я что-то делал неправильно, либо конструктор потока не умеет правильно работать с передачей параметров в PChar, может инициализация или освобождение ресурсов некорректно проходит.

P.S. Ну вот теперь хоть сам могу на вопросы поотвечать пойти, а то все задаю и задаю :)))


 
Kent   (2002-09-05 11:03) [14]

А вот это надо спросить у того кто функцию WaitForSingleObject писал :))
А точно ли на 100% что окно, ожидая результата WIAT_OBJECT_0, перестает обрабатывать сообщения и вызывать WndProc ??


 
Виктор Щербаков   (2002-09-05 11:07) [15]


> А точно ли на 100% что окно, ожидая результата WIAT_OBJECT_0,
> перестает обрабатывать сообщения и вызывать WndProc ??

А каким образом ты попадешь в цикл обработки сообщений, если поток находится в состоянии ожидания?


 
Старый Паскалист   (2002-09-05 11:08) [16]

>Kent ©
>А точно ли на 100% что окно, ожидая результата WIAT_OBJECT_0, >перестает обрабатывать сообщения и вызывать WndProc.

Абсолютно точно.
Когда поток вызывает ф-ю Wait..., процессор просто перестаёт выделять ему время.



 
Kent   (2002-09-05 11:32) [17]


> Как раз и будет этот самый "эффект подвисания" ! ты ж в
> осн.потоке ждешь некоторое время этот мьютекс, не реагируя
> никак на оконные сообщения... Тогда уж MsgWaitForMultipleObjects
> нужно использовать в цикле : и мьютекс дождешься и оконные
> сообщения обрабатывать будешь успевать)


Приношу свои извинения, абсолютно точно ваше замечание, это я чудило тряпошное, я просто заремил функцию WaitForSingleObject в основном контексте... и удивлялся, наивный :))
А можно в двух словах попросить объяснений, как тогда поступить чтобы не "вешать" основной поток ????


 
Виктор Щербаков   (2002-09-05 11:45) [18]


> А можно в двух словах попросить объяснений, как тогда поступить
> чтобы не "вешать" основной поток ????

Например, при окончании работы второго потока посылать сообщение в одно из окон основного потока. Кстати, эти сообщения можно посылать и чаще, тем самым получишь возможность отображать процесс работы. Еще, посмотри TThread.OnTerminate.


 
Старый Паскалист   (2002-09-05 11:46) [19]

Вообще-то объекты синхронизации по своей идее предназначены для защиты участков кода, которые только по случайности могут выполняться одновременно. И обычно стараются сделать защищённые участки как можно более быстрыми.

У тебя же нет никакой случайности. Поэтому нужно просто как-то по другому организовать логику.
Например, по окончании работы поток шлёт сообщение или устанавливает какой-то флаг, что к данным обращаться можно.


 
Kent   (2002-09-05 11:49) [20]

Да, пожалуй буду по Create"у потока устанавливать флаг, а в OnTerminate сбрасывать !!!

Огромное спасибо всем, кто помогал !

P.S. Кстати, я сейчас еще одну темку подкину, это просто вопрос очень занятный, если будет желание, посмотрите ...


 
Digitman   (2002-09-05 11:54) [21]

>Kent

Например , так :

var
Msg: TMsg;
...

while True do
case MsgWaitForMultipleObjects(1, hMutex, False, 1000, QS_ALLINPUT) of
WAIT_OBJECT_0: break; // сигнал "мьютекс свободен"
WAIT_OBJECT_0 + 1: Application.ProcessMessages; //в очередях окон осн.потока процесса есть необработанные сообщения - обработать их
WAIT_ABANDONED: break; // объект-мьютекс больше не существует
WAIT_TIMEOUT: continue; // таймаут ожидания исчерпан - можно еще подождать, если требуется, а можно и выйти из цикла по некоему условию, например, превышено знач-е сч-ка таймаутов ожидания событий




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

Форум: "Основная";
Текущий архив: 2002.09.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.007 c
3-50596
Soft
2002-08-24 15:57
2002.09.16
Какой максимальный размер файла базы у IB6.X на NTFS


14-50963
Durik
2002-08-21 13:18
2002.09.16
Оцените сайт!!!


3-50634
Adoon
2002-08-26 19:15
2002.09.16
БД


1-50793
KPY
2002-08-29 07:44
2002.09.16
Шифрация !


1-50779
DDDeN
2002-09-03 13:00
2002.09.16
Контекстное меню





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский