Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 1 623

/ вопрос открыт /

Здравствуйте!
Впервые столкнулся с такой проблемой, кучу вариантов решения пербрал, я в ступоре. Может вам мой вопрос покажется бессмысленным или некорректным, но я все же попробую задать:
Есть процедура динамической загрузки плагина
//------------------------------------------
Procedure Tform.loadpluginz;
var qu:integer;
begin
// если плугин загружен, выгружаем...
if PlugHandle <> 0 then begin
@UnLoadMain:= GetProcAddress(plugHandle,'UnLoadMain');
if @UnLoadMain <> nil then
UnLoadMain;
FreeLibrary(PlugHandle);
end;
// загружаем новый
PlugHandle := LoadLibrary(pchar(combobox.text));
//загружаем сторонние проедуры , выполняются в других процедурах
//все процедуры объявлены в var как процедуры:procedure;
@PluginEXEC := GetProcAddress(plugHandle,'PluginExec');
//главная процедура, выполняется прямо здесь
@LoadMain:= GetProcAddress(plugHandle,'LoadMain');
if @LoadMain <> nil then
LoadMain;
end;
//------------------------------------------

При запуске программки и исполнении данной процедуры по нескольку раз все отлично, плугины грузятся, все процедуры выполняются! НО стоит выполнить другую процедуру стороннего компонента (например component1.doit), как Исполнение процедур плагина и его дальнейшая выгрузка и загрузка нового становится невозможным!! программа просто выдаёт ошибку (скриншот с ошибкой и цпу приложил к вопросу)
п.с. сам компонент component1 и процедура component1.doit рабочие.

Очень надеюсь на любую помощь!

К вопросу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки вопроса)

Примечание #1 (25 мая 2008, 17:47):
еще хочется сказать: если сначала выполнить component1.doit, а потом уже после загружать плагины, никаких ошибок тоже произойдет.

Phoenix Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Phoenix (статус: Посетитель)
Вопрос отправлен: 25 мая 2008, 16:56
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 5; последнее сообщение — 26 мая 2008, 12:47; участников в обсуждении: 2.
Вадим К

Вадим К (статус: Академик), 25 мая 2008, 18:58 [#1]:

М, ну и сформулировали вопрос...
Во первых, какой смысл скрывать название компонента и процедуры? Может не такой уж он и рабочий.
во вторых, судя по скрину - ошибка где то в системных (а может и ваших) dll. Где именно - сложно судить.
в третих, а не пробовали ли сделать так. Вначале приготовить всё, что бы ошибка гарантировано возникла, и поставивь точку останова на первой строке с помощью F8 пройтись по процедуре и уловить момент, на какой именно строке происходит сбой
Галочка "подтверждения прочтения" - вселенское зло.
Phoenix

Phoenix (статус: Посетитель), 25 мая 2008, 19:46 [#2]:

Спасибо, что отозвались. Похоже сам разобрался. Сбой дает процедура именно при повторном обращении, так что точками это отсладить было невозможно (это я выяснил просто убрав ее из текста главной процедуры).

//разбивает строку на части посредствам символа-разделителя. процедура очень важна. только вот не пойму в каком месте глюк и почему? может предложете альтернативную процедуру подобной функциональности?


procedure StrBreakApart(const S, Delimeter : string; Parts : TStrings);
var
CurPos: integer;
CurStr: string;
begin
Parts.clear;
Parts.BeginUpdate();
try
CurStr:= S;
repeat
CurPos:= Pos(Delimeter, CurStr);
if (CurPos>0) then
begin
Parts.Add(Copy(CurStr, 1, Pred(CurPos)));
CurStr:= Copy(CurStr, CurPos+Length(Delimeter),
Length(CurStr)-CurPos-Length(Delimeter)+1);
end else
Parts.Add(CurStr);
until CurPos=0;
finally
Parts.EndUpdate();
end;
end;
Phoenix

Phoenix (статус: Посетитель), 25 мая 2008, 21:28 [#3]:

все-таки решил воспользоваться дэлимитер TStringList. вот так, если что поправьте!
function StrBreakApart(S: String; Delimiter,Quote: char): TStringList;
var
List: TStringList;
begin
List := TStringList.Create;
with List do begin
QuoteChar :=Quote;
Delimiter :=Delimiter;
DelimitedText := S;
end;
result:= List;
end;

//S:='|часть 1|;|часть 2|;|часть 3| вот такая вот фиговина

Жалко, что приходится использовать QuoteChar, иначе независимо от делимитера будут отделяться части и с пробелами, например:
S:='часть 1;часть 2;часть 3'
//в результате
часть
1
часть
2
часть
3
Ладно, спасибо всем экспертам да и всему порталу за помощь, вы моё спасение! так держать!
Вадим К

Вадим К (статус: Академик), 25 мая 2008, 23:40 [#4]:

На такую странность в разбиении и я натыкался. А всё дело в том, что в коде TStrings немного нахимичено. При поиске разделителя есть такой код
while P^ in [#1..' '] do
      {$IFDEF MSWINDOWS}
        P := CharNext(P);
      {$ELSE}
        Inc(P);
      {$ENDIF}
Убрали бы пробел - жизнь наладилась. Перевод строки ещё как то вписывается, но не пробел. В 2006 и старше (на счёт 2005 не в курсе, в 7 точно нет) есть свойство у TStrings - StrictDelimiter. Если выставить его в True - разбивает как положено. Если у вас версия неподходящая, то есть два варианта - либо самописная процедура, либо вычленить TStrings, хотя непонятно, что будет проще.
Посмотрел я на предыдущий код разделения. На больших строках будет тормозить, причём ужасно. Причина - частый вызов Copy.
Хотя код вроде работоспособный.
Пошурудев немного извилинами, я написал небольшой код, немного изменив сигнатуру (разделитель всё равно один символ, зачем заводить строку?)
Попробуйте код. А вот ответ на вопрос: "А как это работает?" попробуйте найти самостоятельно.
procedure StrBreakApart(const S: string; Delimeter: char; Parts: TStrings);
var
  i, j, l:   integer;
begin
  Parts.Clear;
  Parts.BeginUpdate();
  try
    i := 1;
    j := 1;
    l := length(s);
    while i <= l do
    begin
      while (s[i] <> Delimeter) and (i <= l) do
        Inc(i);
      Parts.Add(copy(s, j, i - j));
      Inc(i);
      j := i;
    end;
  finally
    Parts.EndUpdate();
  end;
end;
Попробуйте оценить скорость работы на больших строках:)
Галочка "подтверждения прочтения" - вселенское зло.
Phoenix

Phoenix (статус: Посетитель), 26 мая 2008, 12:47 [#5]:

всё гениальное - просто! разобрался. спасибо за все, Вадим!
Я даже не ожидал, что такая сложная проблема на первый взгяд приведет к довольно простому решению.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:57
Выполнено за 0.03 сек.