Ary*_*yal 2 delphi dll delphi-xe2
从动态或静态加载程序时从dll加载程序时遇到问题.当我把程序从dll放到我的单位时,一切正常.当我尝试用dll做它时它给了我
第一次机会异常,价格为00526399美元.异常类$ C0000005,消息'访问冲突位于0x00526399:读取地址0x00000390'.处理Project1.exe(21988)
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls,Unit2;
type
TForm1 = class(TForm)
ListView1: TListView;
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Refresh;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
type
plist = ^element;
element = record
artist,title,genre: string[20];
year,grade: integer;
wsk: plist;
end;
database = file of element;
var
base: database;
first: plist;
handler: HModule;
{$R *.dfm}
procedure TForm1.Refresh();
var
current: plist;
begin
ListView1.Clear;
current:= first;
while current<>nil do
begin
with ListView1.Items.Add do
begin
Caption:=current^.artist;
SubItems.Add(current^.title);
SubItems.Add(current^.genre);
SubItems.Add(IntToStr(current^.year));
SubItems.Add(IntToStr(current^.grade));
end;
current:=current^.wsk;
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var Save: procedure;
begin
handler:=LoadLibrary('lib.dll');
try
@Save:=GetProcAddress(handler, PChar(2));
if @Save = nil then raise Exception.Create('Load nie dziala');
Save();
finally
FreeLibrary(handler);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
Load: procedure;
begin
handler:=LoadLibrary('lib.dll');
try
@Load:=GetProcAddress(handler, PChar(1));
if @Load = nil then raise Exception.Create('Load nie dziala');
Load();
finally
FreeLibrary(handler);
end;
Refresh();
end;
procedure TForm1.Button1Click(Sender: TObject);
var
el: element;
Add: procedure(el:element);
begin
el.artist:=Edit1.Text;
el.title:=Edit2.Text;
el.genre:=Edit3.Text;
el.year:=StrToInt(Edit4.Text);
el.grade:=StrToInt(Edit5.Text);
handler:=LoadLibrary('lib.dll');
try
@Add:=GetProcAddress(handler, PChar(3));
if @Add = nil then raise Exception.Create('Load nie dziala');
Add(el);
finally
FreeLibrary(handler);
Refresh();
{Form2:=TForm2.Create(Form1);
Form2.ShowModal;
Form2.Free;}
end;
end;
end.
Run Code Online (Sandbox Code Playgroud)
dll文件如下所示:
library lib;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
System.SysUtils,
System.Classes;
{$R *.res}
type plist = ^element;
element = record
artist,title,genre:string[20];
year,grade:integer;
wsk: plist;
end;
database = file of element;
var
first: plist;
base: database;
procedure add(el: element); stdcall;
var current,tmp: plist;
begin
New(current);
current^ := el;
current^.wsk := nil;
if first = nil then
begin
first:=current;
end else
begin
tmp:=first;
while tmp^.wsk<>nil do
begin
tmp:=tmp^.wsk;
end;
tmp^.wsk:=current;
end;
end;
procedure load();stdcall;
var
el: element;
i: integer;
begin
AssignFile(base, 'baza.dat');
if not FileExists('baza.dat') then
begin
Rewrite(base);
end else
begin
Reset(base);
for i := 0 to FileSize(base)-1 do
begin
read(base, el);
add(el);
end;
end;
CloseFile(base);
end;
procedure save();stdcall;
var
current: plist;
el: element;
begin
AssignFile(base, 'baza.dat');
Rewrite(base);
current:=first;
while current<>nil do
begin
el:=current^;
el.wsk:=nil;
write(base, el);
current:= current^.wsk;
end;
end;
exports
add index 1,
load index 2,
save index 3;
begin
end.
Run Code Online (Sandbox Code Playgroud)
它还向我显示了一个错误:
预期';' 但是在第91行收到了标识符'index'
但是出口就像我在网上的红色一样.
明显的错误是:
LoadLibrary始终成功.stdcall在DLL和register可执行文件中使用.坦率地说,这段代码真是一团糟.我建议你做以下事情:
external在可执行文件中使用关键字.这将通过删除所有这些调用大大简化代码LoadLibrary,GetProcAddress等等.如果需要运行时链接,您可以在以后通过添加delayed关键字.PChar在模块边界使用而不是短字符串.TList<T>在DLL中使用来存储元素列表.