Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1306831572
Max
2011-05-31 12:46
2011.09.11
массивы


2-1306745074
Очень злой
2011-05-30 12:44
2011.09.11
Можно ли создать объект не известного заранее класса


2-1306413330
Очень злой
2011-05-26 16:35
2011.09.11
Inherited


2-1306758590
Неважно
2011-05-30 16:29
2011.09.11
ф-ция GetForegroundWindow


2-1305642710
Алеша
2011-05-17 18:31
2011.09.11
Работа с txt





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский