Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Access Violation при вызове функции из DLL 
V
    Опции темы
mr.Anderson
Дата 7.8.2007, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 3
Всего: 128



Возникла проблема при написании DLL.

Собственно код DLL:
Код

library MyLib;

uses
  SysUtils,
  Classes;

{$R *.res}

function Verify(): Boolean; stdcall; export;
begin
 Result := True;
end;

function GetFileExpression(): String; stdcall; export;
begin
 Result := 'MyExpression';
end;

exports
 Verify,
 GetFileExpression;

begin
end.

DLL позиционируется как плагин к моей программе. В связи с этим я ввел глобальный тип:
Код

type
 TPlugin = record
  Module   : HMODULE;
  FullName : AnsiString;
  Name     : AnsiString;
 end;

А также глобальный динамический массив с плагинами:
Код

var
 plugins : array of TPlugin;

Код загрузки плагинов:
Код

procedure TForm1.LoadPlugins;

 //verifying
 function VerifyPlugin( fullpath: AnsiString ): Boolean;
 var
  lib  : HMODULE;
  func : function: Boolean; stdcall;
 begin
  Result := False;

  lib := LoadLibrary( PAnsiChar( fullpath ) );
  if( lib = 0 ) then
   Exit;

  @func := GetProcAddress( lib, 'Verify' );
  if( Assigned( @func ) ) then
   Result := func();

  FreeLibrary( lib );
 end;

 //loading
const
 path : AnsiString = 'plugins\';
var
 count : Integer;
 srec  : TSearchRec;
begin
 count := 0;

 if( FindFirst( path + '*', faAnyFile, srec ) then
 begin
  repeat
   if( srec.Name <> '.' ) and ( srec.Name <> '..' ) then
    if( VerifyPlugin( path + srec.Name ) ) then
    begin
     Inc( count );
     SetLength( plugins, count );

     plugins[ count-1 ].Module   := LoadLibrary( PAnsiChar( path + srec.Name ) );
     plugins[ count-1 ].FullName := path + srec.Name;
     plugins[ count-1 ].Name     := srec.Name;
    end;
  until FindNext( srec ) <> 0;

  FindClose( srec );
 end;
end;

Код вызова функции из DLL выглядит так (именно здесь происходит ошибка, судя по заверениям отладчика):
Код

procedure TForm1.FormShow( Sender: TObject );
var
 GetFileExpression : function(): String; stdcall;
begin
 LoadPlugins();
 @GetFileExpression := GetProcAddress( plugins[0].Module, 'GetFileExpression' );
 if( Assigned( @GetFileExpression ) ) then
  ShowMessage( GetFileExpression() );
end;

Ошибка в следующем. Выполнение (по отладчику), доходит до строки ShowMessage( GetFileExpression() ); (из последнего фрагмента кода). Верно выводит сообщение с правильным текстом (как в DLL описано). Однако, после этого вылетает Access Violation с ошибкой 'Недопустимая операция с указателем' ('Invalid Pointer Operation'). Как я ни пытался отловить ошибку - найти ее причину не смог. Ошибка 100% где-то в приведенных фрагментах кода, т.к. если убрать вызов ShowMessage, то Access Violation не возникает.

Вопрос описал достаточно подробно, надеюсь. Кто может помочь?

Это сообщение отредактировал(а) mr.Anderson - 7.8.2007, 17:11


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
Snowy
Дата 7.8.2007, 17:25 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 31
Всего: 484



Ну так кто ж тебя учил юзать стринги в dll?
Да ещё для плагинов...
Сейчас конечно тебе тут напомнят про ShareMem...
Но что за плагин, если его можно только на дельфи написать?
Тогда уж bpl юзай.
Или используй общие типы: pointer, dword, PChar...
PM MAIL   Вверх
ASGDeveloper
Дата 7.8.2007, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


developer
**


Профиль
Группа: Участник
Сообщений: 389
Регистрация: 1.4.2006

Репутация: нет
Всего: 1



Цитата(mr.Anderson @  7.8.2007,  17:10 Найти цитируемый пост)
Вопрос описал достаточно подробно, надеюсь. Кто может помочь?

Все компилится и работает. Бага где-то в другом месте.
PM MAIL   Вверх
mr.Anderson
Дата 7.8.2007, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 3
Всего: 128



А у меня не компилится и не работает. Даже с ShareMem. После его подключения эта же ошибка стала лезть после закрытия приложения.

Добавлено через 7 минут и 28 секунд
В общем, вопрос решил. Через FastShareMem и обход глюков в OnClose формы.


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
skyboy
Дата 10.8.2007, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: нет
Всего: 260



ShareMem должно быть первым в списке как в библиотеке, так и в твоем приложении(не в unit1.pas, а в dpr-файле!) 
тогда никаких глюков не будет.
впрочем, Showy прав - тогда уж лучше bpl юзать, раз связь с другими ЯП не прредусматривается
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0556 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.