Форум: "Начинающим";
Текущий архив: 2011.09.11;
Скачать: [xml.tar.bz2];
ВнизГде ошибка в программе? Найти похожие ветки
← →
Delphi beginner © (2011-05-28 15:54) [0]Используя вместо DLL-файла встроенный в exe-файл модуль Unitdll, программа работает без ошибок. Ошибка (Runtime error 216) появляется при вызове функции GetNextLine в строке:
while Filter.GetNextLine(S) do
после ее выполнения некоторое количество раз (для каждого текстового файла - разное),
когда указатель Filter, возможно, теряет значение адреса.
Содержимое файла plugins.ini:
[Filters]
TXT=ImpTxt.dll
Текст модуля, подключаемого к основной программе:
unit FormUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, PluginInterface, IniFiles, ComCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
OpenDialog1: TOpenDialog;
StatusBar1: TStatusBar;
procedure Button1Click(Sender: TObject);
procedure LoadData(FileName: String);
private
{ Private declarations }
public
{ Public declarations }
end;
TAPI = class(TInterfacedObject, IAPI)
procedure ShowMessage(const S: String);
end;
TCreateFilter = function: ILoadFilter; stdcall;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TAPI }
procedure TForm1.LoadData(FileName: String);
var
PluginName: String;
Ext: String;
hPlugIn: THandle;
CreateFilter: TCreateFilter;
Filter: ILoadFilter;
S: String;
begin
Memo1.Lines.Clear;
Memo1.Lines.BeginUpdate;
try
Ext := ExtractFileExt(FileName);
Delete(Ext, 1, 1);
with TIniFile.Create(ExtractFilePath(ParamStr(0)) + "plugins.ini") do
try
PlugInName:= ReadString("Filters", Ext, "");
finally
Free;
end;
hPlugIn := LoadLibrary(PChar(PluginName));
try
CreateFilter := GetProcAddress(hPlugIn, "CreateFilter");
if Assigned(CreateFilter) then
begin
Filter:=CreateFilter;
try
Filter.Init(Filename, TAPI.Create);
while Filter.GetNextLine(S) do
Memo1.Lines.Add(S)
finally
Filter:=nil;
end;
end else raise Exception.Create("Не могу загрузить фильтр");
finally
if hPlugIn <> 0 then
FreeLibrary(hPlugIn);
end;
finally
Memo1.Lines.EndUpdate;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
Loaddata(OpenDialog1.FileName)
end;
procedure TAPI.ShowMessage(const S: String);
begin
with (Application.MainForm as TForm1).StatusBar1 do
begin SimpleText := S;
Update;
end;
end;
end.
library ImpTxt;
uses
ShareMem,
SysUtils,
Classes,
PluginInterface,
Unitdll in "Unitdll.pas";
{$R *.RES}
exports
CreateFilter;
begin
end.
Текст модуля, подключаемого к DLL:
unit Unitdll;
interface
uses
SysUtils, Classes, PluginInterface;
type
TTextFilter = class(TInterfacedObject, ILoadFilter)
private
FAPI: IAPI;
F: TextFile;
Lines: Integer;
InitSuccess: Boolean;
procedure Init(const FileName: String; API: IAPI);
function GetNextLine(var S: String): Boolean;
public
destructor Destroy; override;
end;
function CreateFilter:ILoadFilter; stdcall;
implementation
{ TTextFilter}
procedure TTextFilter.Init(const FileName: String; API: IAPI);
begin
FAPI := API;
{$I-}
AssignFile(F, FileName);
Reset(F) ;
{$I+}
InitSuccess := IOResult = 0;
if not InitSuccess then
API.ShowMessage("Ошибка инициализации загрузки");
end;
function TTextFilter.GetNextLine(var S: String):Boolean;
begin
if InitSuccess then
begin
Inc(Lines) ;
Result := not Eof(F);
if Result then
begin
Readln(F, S);
FAPI.ShowMessage("Загружено " +
IntToStr(Lines) + " строк.");
end;
end else
Result := FALSE;
end;
destructor TTextFilter.Destroy;
begin
FAPI := nil;
if InitSuccess then CloseFile(F);
inherited;
end;
function CreateFilter: ILoadFilter;
begin
Result := TTextFilter.Create;
end;
end.
Текст модуля, описывающего интерфейс:
unit PluginInterface;
interface
type
IAPI = interface
["{64CFF1E0-61A3-11D4-84DD-B18D6F94141F}"]
procedure ShowMessage(const S: String);
end;
ILoadFilter = interface
["{64CFF1E1-61A3-11D4-84DD-B18D6F94141F}"]
procedure Init(const FileName: String; API: IAPI);
function GetNextLine(var S: String): Boolean;
end;
implementation
end.
← →
KSergey © (2011-05-28 17:09) [1]> function GetNextLine(var S: String): Boolean;
На первый взгляд - стандартный совет почитать комментарий, вставляемый средой при создании нового проекта DLL, там про ShareMem написано что-то, вот это и надо почитать. Ну или погуглить по этому слову, если хочется по-русски.
Но ведь еще и интерфейсы прикручены зачем-то, причем есть подозрение - не COM. Тогда зачем?
← →
_Юрий (2011-05-29 11:17) [2]Интерфейсы - вещь хорошая и безо всякого COM.
насчет ShareMem - в коде видно, что в библиотеке он включен, а включен ли также и в хосте-надо посмотреть.
← →
Delphi beginner © (2011-05-31 01:21) [3]Спасибо, Юрий! Думаю, что Вы правы.
← →
Германн © (2011-05-31 01:32) [4]
> Delphi beginner ©
Научись форматировать код!
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2011.09.11;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.003 c