![]()  | 
	
 
  | 
		
			
  | 	
	
	
		
		|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны | 
![]()  | 
	
	
| 
		 | 
	Опции темы | Поиск в этой теме | Опции просмотра | 
| 
		 
			 
			#1  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Вопрос относительно использования технологии Plug-in в Delphi 
		
	
		
		
		
		
		
	
		
		
	
	
	вот код интерфейснго модуля Код: 
	
unit FileInterface;
interface
type
  IAPI = interface
   ['{0F252623-FDFD-4F31-8198-217590C478E4}']
   procedure IMessage(const msg:string);
   procedure IErrMessage(const errmsg:string);
  end;
  IConvertor = interface
   ['{3DD00461-76F3-4BF6-9918-C198CCBA875B}']
   procedure Init(const InFName:string; API:IAPI);
   function Convert:boolean;
  end;
implementation
end.код простейшего plug-in в DLL Код: 
	library ConvertHTML;
uses
  Sharemem,SysUtils,Classes,FileInterface;
{$R *.res}
type
  TConvertHTML = class (TInterfacedObject,IConvertor)
   private
    FAPI        : IAPI;
    FName       : string;
    InitSuccess : Boolean;
   procedure Init(const InFName:string; API:IAPI);
   function Convert:boolean;
   public
    destructor Destroy; override;
   end;
{ TConvertHTML }
procedure TConvertHTML.Init(const InFName: string; API: IAPI);
begin
FAPI:=API;
FName:=InFName;
if FAPI <> nil then
 begin
  if FileExists(FName) then
  begin
   InitSuccess := true;
   FAPI.IMessage('Инициализация прошла успешно');
  end
  else
  begin
  InitSuccess:=false;
  FAPI.IErrMessage('Файл '+FName+' не найден или не существует');
  FAPI:=nil;
  end;
 end;
end;
function TConvertHTML.Convert: boolean;
var i         :integer;
    _stime    :string;
    _saction  :string;
    _sIP      :string;
    _snamefile:string;
    tmpstr    :string;
    CurPos    :integer;
    InF,OutF  :TStringList;
begin
if InitSuccess then
 begin
  InF:=TStringList.Create;
  InF.LoadFromFile(FName);
  OutF:=TStringList.Create;
  OutF.Add('<html>');
  OutF.Add('<body>');
  OutF.Add('<table border=2>');
  OutF.Add('<tr>');
  OutF.Add('<td bgcolor="#ff00ff">Time</td>');
  OutF.Add('<td bgcolor="#ff00ff">IP</td>');
  OutF.Add('<td bgcolor="#ff00ff">Action</td>');
  OutF.Add('<td bgcolor="#ff00ff">Name</td>');
  OutF.Add('</tr>');
  i:=0;
 repeat
  tmpstr:=InF.Strings[i];
    CurPos := Pos(';', tmpstr);
     if (CurPos > 0) then
      begin
       _stime:=Copy(tmpstr, 1, Pred(CurPos));
       tmpstr := Copy(tmpstr, CurPos + 1,
          Length( tmpstr) - CurPos - 1 + 1);
      end;
     CurPos := Pos(';', tmpstr);
     if (CurPos > 0) then
      begin
       _sIP:=Copy(tmpstr, 1, Pred(CurPos));
       tmpstr := Copy(tmpstr, CurPos + 1,
          Length( tmpstr) - CurPos - 1 + 1);
      end;
      CurPos := Pos(';', tmpstr);
     if (CurPos > 0) then
      begin
       _saction:=Copy(tmpstr, 1, Pred(CurPos));
       tmpstr := Copy(tmpstr, CurPos + 1,
          Length( tmpstr) - CurPos - 1 + 1);
      end;
      CurPos := Pos(';', tmpstr);
     if (CurPos > 0) then
      begin
       _snamefile:=Copy(tmpstr, 1, Pred(CurPos));
       tmpstr := Copy(tmpstr, CurPos + 1,
          Length( tmpstr) - CurPos - 1 + 1);
      end
      else
        _snamefile:=tmpstr;
   OutF.Add('<tr>');
   OutF.Add('<td>'+_stime+'</td>');
   OutF.Add('<td>'+_sIP+'</td>');
   OutF.Add('<td>'+_saction+'</td>');
   OutF.Add('<td>'+_snamefile+'</td>');
   OutF.Add('</tr>');
    inc(i);
 until i = InF.Count;
  FAPI.IMessage('файл '+FName+' преобразован');
  FName:=ChangeFileExt(FName,'.html');
  OutF.Add('</table>');
  OutF.Add('</body>');
  OutF.Add('</html>');
  OutF.SaveToFile(FName);
  InF.Free;
  OutF.Free;
  FAPI.IMessage('файл '+FName+' сохранен');
  Result:=true;
end
else Result:=false;
end;
destructor TConvertHTML.Destroy;
begin
  FAPI:=nil;
  inherited;
end;
function CreateConvert:IConvertor;
begin
  Result :=  TConvertHTML.Create;
end;
exports
  CreateConvert ;
begin
end.а вот тестовый пример использующий этот плагин Код: 
	
unit main;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    OpenDialog1: TOpenDialog;
    GroupBox1: TGroupBox;
    GroupBox2: TGroupBox;
    ErrorMem: TMemo;
    DataMem: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    procedure LoadData(FileName: String);
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
uses FileInterface;
type
  TAPI = class(TInterfacedObject, IAPI)
   procedure IMessage(const msg:string);
   procedure IErrMessage(const errmsg:string);
   destructor Destroy; override;
  end;
{ TAPI }
destructor TAPI.Destroy;
begin
  inherited;
end;
procedure TAPI.IErrMessage(const errmsg: string);
begin
 with (Application.MainForm as TForm1).ErrorMem do begin
    Lines.Add(errmsg);
    Update;
  end;
end;
procedure TAPI.IMessage(const msg: string);
begin
 with (Application.MainForm as TForm1).DataMem do begin
    Lines.Add(msg);
    Update;
  end;
end;
type
 TCreateConvertor = function : IConvertor;
{ TForm1 }
procedure TForm1.LoadData(FileName: String);
var
  PluginName      : String;
  hPlugIn         : THandle;
  CreateConvertor : TCreateConvertor;
  Convertor       : IConvertor;
begin
PlugInName:=Edit1.Text;
hPlugIn := LoadLibrary(PChar(PluginName));
CreateConvertor := GetProcAddress(hPlugIn, 'CreateConvert');
if Assigned(CreateConvertor) then
 begin
  Convertor:=CreateConvertor;
   try
    Convertor.Init(FileName,TAPI.Create);
    Convertor.Convert;
   finally
    Convertor:=nil;
   end;
 end;
FreeLibrary(hPlugIn);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
    LoadData(OpenDialog1.FileName);
end;
end.Если в кратце описать, что делает этот плаг - преобразует внутренний формат файла в формат HTML. Дак вот проблема в том , что когда я вызываю из тестового примера FreeLibrary(hPlugIn); прога вылетаеет с AV Цитата: 
	
  | 
| 
		 
			 
			#2  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Вопрос, а она выполняет конвертацию-то? 
		
	
		
		
		
		
		
	
		
		
	
	
	Собственно, где проверки на то, что либа загрузилась и получен правильный адрес функции. Это раз. во вторых, мне, например, в принципе не нравится то, что сдесь смешаы 2 технологии - обычная DLL и COM. Советую выбрать что-либо одно. Может быть именно из-за этого все и происходит - у тебя обнуляется счетчик ссылок в finally и система может успеть выгрузить либу.  | 
| 
		 
			 
			#3  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 проверки есть, длл отрабатывает, AV выскакивает привыгрузке длл, 
		
	
		
		
		
		
		
	
		
		
	
	
	я по ошибке вижу что пытаюсь достучаться до несуществующего адреса (метода) а вот где это происходит немогу понять.  | 
| 
		 
			 
			#4  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 можно закрывать топик, проблема решена 
		
	
		
		
		
		
		
	
		
		
	
	
	в строке "Convertor.Init(FileName,TAPI.Create);" может быть неявная переменная, которая освобождается после FreeLibrary. это и вызывало ошибку, ну еще поменял тип string на WideString, теперь окончательный вариант выглядит следующим образом: Код: 
	procedure TForm1.LoadData(FileName: String);
var
  PluginName        : String;
  hPlugIn             : THandle;
  CreateConvertor : TCreateConvertor;
  Convertor          : IConvertor;
  PAPI                 : TAPI;
begin
PlugInName:=Edit1.Text;
hPlugIn := LoadLibrary(PChar(PluginName));
CreateConvertor := GetProcAddress(hPlugIn, 'CreateConvert');
if Assigned(CreateConvertor) then
 begin
  if CreateConvertor(Convertor) then
 begin
   try
    PAPI:=TAPI.Create;
    Convertor.Init(FileName,PAPI);
    Convertor.Convert;
   finally
    Convertor:=nil;
    PAPI:=nil;
   end;
 end;
 end;
FreeLibrary(hPlugIn);
end; |