Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.07.2015, 12:27   #1
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию Access violation at address...

Здравствуйте, граждане-товарищи...
Никак не могу понять, что за проблема.
Решил сделать DLL-ку для поиска музыки на сайте. Но что-то работает непонятно. Вроде, сам цикл поиска в DLL проходит
Код:
Function GetSongGrid(SongName:PAnsiChar; Limit:Integer{; ProcessVis:TProgressBar}):PAnsiChar; stdcall; export;
var i_site:Integer;
    ZaprKompozits,html,SongUrl,html2,TmpStr:String;

  procedure GetTextAfter(Substr:String; var StString:String);
  begin
    Delete(StString,1,pos(Substr,StString)+Length(Substr)-1);
  end;

Begin
  ShowMessage('Попытка поиска через плагин');

// =========== Поиск на pesni-tut.net =============
  i_site:=0;
  html:='';
  ZaprKompozits:=SongName;
  ZaprKompozits:=AnsiReplaceStr(ZaprKompozits,' ','+');
  Try
    html:=GetSiteCode('pesni-tut.net','s.php?q='+URLEncode(ZaprKompozits));
  except
    ShowMessage('Ошибка при получении кода страницы');
  end;
  Result:='';


  if pos('" class="blok_pesni">',html)>0 then
  begin
    While (pos('" class="blok_pesni">',html)>0) and (i_site<Limit) do
    try
      ShowMessage('Вход в цикл'+#13+'Шаг: '+IntToStr(i_site));
      if Limit<>0 then inc(i_site);
      GetTextAfter('" class="blok_pesni"',html);
      GetTextAfter('" title="Слушать песню ',html);
      TmpStr:=Copy(html,1,Pos(' бесплатно" alt="',html));
      Result:=PChar(Result+TmpStr+#9);
      ShowMessage(TmpStr);
      GetTextAfter(' онлайн бесплатно" trackid="',html);
      TmpStr:=Copy(html,1,Pos('" class="',html));
      Result:=PChar(Result+TmpStr+#9+#13#10);
      ShowMessage('Выход из цикла'+#13+'Шаг: '+IntToStr(i_site)+#13+'Следующий вход песни: '+IntToStr(pos('" class="blok_pesni">',html)));
    except
      ShowMessage('Ошибка в обработке данных'+#13+'Шаг: '+IntToStr(i_site));
    end;

  end;
  ShowMessage('Обработка закончена.'+#13+'Найдено песен: '+IntToStr(i_site));
// =========== Конец поиска на pesni-tut.net =============
End;
А вот на следующей процедуре в программе периодически возникает указанная в теме ошибка, не зависимо от того, что идёт следом.
Код:
  LoadMyLibrary(CheckListBox1.Items.Strings[CheckListBox1.ItemIndex]+'.dll');
  ShowMessage(GetSongGrid(PChar(Edit1.Text),10));
  FreeLibrary(LibHandle);
Причём, ошибка возникает не всегда. На "Алиса - Театр теней" работает. На "Tequilajazzz - Зимнее солнце" - не работает. Не работает, если находится больше одной песни. Но DLL проходит до конца: последний ShowMessage отображается.

Где может быть проблема?...
Если пытаюсь ввести переменнную типа PAnsiChar
Код:
N=GetSongGrid(PChar(Edit1.Text),10)
программа почему-то "прекращает работу" странным образом без сообщения об ошибке, но "аварийно".
Как выйти из ситуации?..
Ship_1 вне форума Ответить с цитированием
Старый 22.07.2015, 13:06   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Меня могут сейчас закидать помидорами некоторые форумчане, но лично я с ДЛЛ работаю так:
Код:
Function GetSongGrid(SongName:PAnsiChar; Limit:Integer; Playlist:TStrings):Boolean; stdcall; export;
begin
...
try
 ...
  Playlist.Append(...);
 ...
 Result:=true;
except
 result:=false;
end;
end;
И вызов:
Код:
var st:TStringlist;
begin
 ...
 if GetSongGrid('Король и Шут - Мертвый анархист',st) then 
  в st список строк
 else
  Какая-то ошибка.
Т.е. передачу строк делаю через класс-обертку.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 22.07.2015, 13:40   #3
ResourceSpace
Форумчанин
 
Аватар для ResourceSpace
 
Регистрация: 30.06.2015
Сообщений: 353
По умолчанию

Где код DLL, а где не DLL? Как оно загружается весь код покажите.
Код:
FreeLibrary(LibHandle);
А где ж оно инициализируется?
ResourceSpace вне форума Ответить с цитированием
Старый 22.07.2015, 13:57   #4
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

ResourceSpace Намекаете, что проблема в инициализации? Разве тогда могла бы она у меня хоть при каких-то запросах нормально работать? Инициализируется в другой, отдельной, процедуре.
Stilet, спасибо за вариант, но, если я правильно понимаю, при String и StringList нужно что-то хитрое с памятью делать. Указатели, выделения памяти и потоки для меня пока тёмный лес. Как поля в физике - что-то мифическое Хотя, конечно, так намного удобнее, но нет ли возможности обойтись строкой?
Ship_1 вне форума Ответить с цитированием
Старый 22.07.2015, 14:21   #5
ResourceSpace
Форумчанин
 
Аватар для ResourceSpace
 
Регистрация: 30.06.2015
Сообщений: 353
По умолчанию

Я не намекаю, просто по такому кусочку сложно судить. Вижу FreeLibrary, а где оно взялось? Это глобальная переменная, локальная? Поле класса? А оно не пустое ли случайно? А откуда берётся функция GetSongGrid()?
Вообще следует ставить проверки после попытки загрузить, не равно ли нулю. Плюс:
Код:
Try
      ...
Except
      On E:Exception Do
            Begin
            ShowMessage(SysErrorMessage(GetLastError()));
            ShowMessage('Exeption: '+E.Message);
            End;
      End;
И вместо ShowMessage попробуйте в DLL писать как-то иначе. Вывод в файл, или отправлять в программу текст, а там добавлять в Memo.
ResourceSpace вне форума Ответить с цитированием
Старый 22.07.2015, 14:39   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
при String и StringList нужно что-то хитрое с памятью делать.
При string да - Sharemem подключать или Fastmem. А если использовать объект то ниче делать не придется.
Цитата:
нет ли возможности обойтись строкой?
Я тее честно признаюсь - никогда не старался в ДЛЛ работать со строками. Уж больно геморройное это дело.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 22.07.2015, 14:39   #7
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

ResourceSpace Взялось оно здесь:
Код:
Procedure LoadMyLibrary(FileName: String);
Begin
  LibHandle:= LoadLibrary(PChar(FileName));
  If LibHandle = 0 then begin
    MessageBox(0,'Невозможно загрузить библиотеку',0,0);
    Exit;
  End;
  GetSongGrid:= GetProcAddress(LibHandle,'GetSongGrid');
  If @GetSongGrid = nil then begin
    MessageBox(0,'Невозможно загрузить библиотеку',0,0);
    Exit;
  End;
End;
Переменная:
Код:
var
  Form1: TForm1;

  LibHandle: HModule; //Ссылка на модуль библиотеки
  FirstCall: procedure; stdcall;
  GetSongGrid: Function(SongName:PAnsiChar; Limit:Integer):PAnsiChar; stdcall;
Цитата:
А откуда берётся функция GetSongGrid()?
Как это понять? Из DLLки и берётся...

Stilet Попробовал.

Код:
var
  GettingString,OutText:PAnsiChar;
  PlLst:TStringList;
begin
  PlLst:=TStringList.Create;
  LoadMyLibrary(CheckListBox1.Items.Strings[CheckListBox1.ItemIndex]+'.dll');

  if GetSongGrid(PChar(Edit1.Text),10,PlLst) then
    ShowMessage('Вышли из процедуры'+#13+PlLst.Text)
   else
    ShowMessage('Снова неудача');

  ShowMessage('Данные получены');
  FreeLibrary(LibHandle);
  ShowMessage('Библиотека выгружена');
  PlLst.Free;
end;
Теперь даже в том варианте, который работал (Алиса - Театр теней) выдаёт ошибку после появления сообщения 'Библиотека выгружена'. А в остальных случаях работа программы стала обрываться без сообщения об ошибке после вывода 'Вышли из процедуры', а иногда и раньше...
Вот с таким окошком появляется обрывание работы:

Буду называть её в дальнейшем виндошибкой.

Последний раз редактировалось Ship_1; 22.07.2015 в 15:14.
Ship_1 вне форума Ответить с цитированием
Старый 22.07.2015, 15:14   #8
ResourceSpace
Форумчанин
 
Аватар для ResourceSpace
 
Регистрация: 30.06.2015
Сообщений: 353
По умолчанию

Из GetProcAddress берётся гм... Всё верно, почти... Давайте немного перенесём FreeLibrary и подкоректиреум логику вот так:
Код:
Procedure TForm1.FormCreate(Sender: TObject);
Begin
LibHandle:=0;
End;

Procedure TForm1.FormDestroy(Sender: TObject);
Begin
If LibHandle<>0 Then
      FreeLibrary(LibHandle);
End;

Function LoadMyLibrary(FileName: String): BooLean;
Begin
Result:=False;
If LibHandle<>0 Then
      FreeLibrary(LibHandle);
LibHandle:=LoadLibrary(PChar(FileName));
If LibHandle<>0 Then
      Begin
      GetSongGrid:=GetProcAddress(LibHandle, 'GetSongGrid');
      If @GetSongGrid<>Nil Then
            Result:=True;
      End;
End;

Procedure TForm1.Button1Click(Sender: TObject);
Var i: Integer; DllName, Ret: String;
Begin
DllName:='test.dll'; // CheckListBox1.Items.Strings[CheckListBox1.ItemIndex]+'.dll';
If FileExists(DllName) Then
      If LoadMyLibrary(DllName) Then
            Begin
            Ret:=GetSongGrid(PChar(Edit1.Text), 10);
            ShowMessage(Ret);
            End
      Else
            MessageBox(Handle, PChar('Не удалось загрузить dll-библиотеку "'+DllName+'"'), Nil, 0)
Else
      MessageBox(Handle, PChar('Не найдена dll-библиотека "'+DllName+'"'), Nil, 0);
End;
На какой строке и какая будет ошибка?
ResourceSpace вне форума Ответить с цитированием
Старый 22.07.2015, 15:26   #9
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Ship_1
А можешь весь свой проект прикрепить сюда с библой?
Так по отрывкам трудно понять.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 22.07.2015, 15:37   #10
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

ResourceSpace
DLLку проходит до последнего ShowMessage, а вот ShowMessage(Ret) появиться не успевает: выскакивает ошибка.
Stilet. ОК, приложил.
Вложения
Тип файла: zip Попытки.zip (211.4 Кб, 9 просмотров)

Последний раз редактировалось Ship_1; 22.07.2015 в 15:45.
Ship_1 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Access violation at address XXXXXX in module 'YYYYYY'. Read of address ZZZZZZ' nik-kang Помощь студентам 0 18.06.2012 22:22
Ошибка: "Access violation at address 0045E503 in module 'Project1.exe'. Read of address 00316777. Katexxxsa Общие вопросы Delphi 1 03.10.2011 23:16
Access violation at address 004733C4 in module 'loginin.exe'. Read of address 00000048' pavellyba Общие вопросы Delphi 2 18.08.2011 10:32
Access violation at address 00447E73 in modul Project.exe. Read of address 00000057. ArtGrek Общие вопросы Delphi 40 12.03.2011 22:03
Access violation at address 00478D0E in module 'Project1.exe'. Write of address 00000000 fondreykus-1 Общие вопросы Delphi 5 27.01.2010 14:25