尝试从dll加载过程时Delphi中出现错误
从dll加载过程时,无论是动态加载还是静态加载,我都遇到了问题。当我把程序从dll放到我的单元中时,一切都很好。当我尝试用dll做它时,它会给我 第一次机会例外价格为00526399美元。异常类别$C0000005,消息为“0x00526399处的访问冲突:读取地址0x00000390”。Process Project1.exe(21988)尝试从dll加载过程时Delphi中出现错误,delphi,dll,delphi-xe2,Delphi,Dll,Delphi Xe2,从dll加载过程时,无论是动态加载还是静态加载,我都遇到了问题。当我把程序从dll放到我的单元中时,一切都很好。当我尝试用dll做它时,它会给我 第一次机会例外价格为00526399美元。异常类别$C0000005,消息为“0x00526399处的访问冲突:读取地址0x00000390”。Process Project1.exe(21988) 单元1; 接口 使用 Winapi.Windows、Winapi.Messages、System.SysUtils、System.Variants、Sys
单元1;
接口
使用
Winapi.Windows、Winapi.Messages、System.SysUtils、System.Variants、System.Classes、Vcl.Graphics、,
Vcl.控件、Vcl.窗体、Vcl.对话框、Vcl.StdCtrls、Vcl.ComCtrls、Unit2;
类型
TForm1=类(TForm)
ListView1:TListView;
按钮1:t按钮;
按钮2:t按钮;
编辑1:TEdit;
编辑2:TEdit;
编辑3:TEdit;
编辑4:TEdit;
编辑5:TEdit;
过程表单创建(发送方:ToObject);
过程FormClose(发送方:ToObject;var操作:TCloseAction);
程序刷新;
程序按钮1点击(发送方:ToObject);
私有的
{私有声明}
公众的
{公开声明}
结束;
变量
表1:TForm1;
实施
类型
plist=^元素;
元素=记录
艺术家、头衔、流派:弦乐[20];
年份、年级:整数;
wsk:plist;
结束;
数据库=元素的文件;
变量
数据库:数据库;
第一:plist;
处理程序:HModule;
{$R*.dfm}
过程TForm1.Refresh();
变量
当前:plist;
开始
ListView1.Clear;
电流:=第一;
而我做不到
开始
使用ListView1.Items.Add do
开始
标题:=当前^艺术家;
子项。添加(当前^标题);
添加子项(当前^体裁);
增加(IntToStr(本年度));
增加(IntToStr(当前等级));
结束;
当前:=当前^.wsk;
结束;
结束;
过程TForm1.FormClose(发送方:TObject;var操作:TCloseAction);
var保存:程序;
开始
处理程序:=LoadLibrary('lib.dll');
尝试
@Save:=GetProcAddress(处理程序,PChar(2));
如果@Save=nil,则引发异常.Create('Load nie dziala');
Save();
最后
免费图书馆(handler);
结束;
结束;
过程TForm1.FormCreate(发送方:TObject);
变量
加载:程序;
开始
处理程序:=LoadLibrary('lib.dll');
尝试
@Load:=GetProcAddress(处理程序,PChar(1));
如果@Load=nil,则引发异常。Create('Load nie dziala');
加载();
最后
免费图书馆(handler);
结束;
刷新();
结束;
程序TForm1.按钮1单击(发送方:TObject);
变量
el:元素;
新增:程序(el:要素);
开始
el.艺术家:=Edit1.Text;
el.title:=Edit2.Text;
el.类型:=Edit3.Text;
el.年份:=标准输入(编辑4.文本);
el.grade:=STROTINT(编辑5.Text);
处理程序:=LoadLibrary('lib.dll');
尝试
@Add:=GetProcAddress(处理程序,PChar(3));
如果@Add=nil,则引发异常.Create('Load nie dziala');
加(el);
最后
免费图书馆(handler);
刷新();
{Form2:=TForm2.Create(Form1);
表2.1;
Form2.Free;}
结束;
结束;
结束。
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.
lib库;
{有关DLL内存管理的重要注意事项:ShareMem必须是
库的USES子句中的第一个单元和项目的(选择
项目视图(源代码)如果DLL导出任何过程或
将字符串作为参数或函数结果传递的函数
应用于从DLL传递到DLL的所有字符串,即使是
嵌套在记录和类中。ShareMem是
BORLNDMM.DLL共享内存管理器,必须随
要避免使用BORLNDMM.DLL,请传递字符串信息
使用PChar或短字符串参数。}
使用
System.SysUtils,
系统、班级;
{$R*.res}
类型plist=^element;
元素=记录
艺术家、头衔、流派:弦乐[20];
年份、年级:整数;
wsk:plist;
结束;
数据库=元素的文件;
变量
第一:plist;
数据库:数据库;
程序添加(el:元素);stdcall;
无功电流,tmp:plist;
开始
新的(当前的);
当前^:=el;
当前^.wsk:=nil;
如果first=nil,则
开始
第一:=电流;
结束其他
开始
tmp:=第一;
而tmp^.wsknil
开始
tmp:=tmp^.wsk;
结束;
tmp^.wsk:=当前;
结束;
结束;
程序加载();stdcall;
变量
el:元素;
i:整数;
开始
AssignFile(基'baza.dat');
如果文件不存在('baza.dat'),则
开始
重写(基础);
结束其他
开始
复位(基本);
对于i:=0的文件大小(基本)-1 do
开始
读取(基准,el);
加(el);
结束;
结束;
关闭文件(基本);
结束;
程序保存();stdcall;
变量
当前:plist;
el:元素;
开始
AssignFile(基'baza.dat');
重写(基础);
电流:=第一;
而我做不到
开始
el:=当前^;
el.wsk:=零;
写入(基,el);
当前:=当前^.wsk;
结束;
结束;
出口
添加索引1,
负荷指数2,
保存索引3;
开始
结束。
它还向我显示了一个错误:
期望“;”但在第91行接收到和标识符“index”
但是导出是像web上的红色一样完成的。明显的错误是:
- 您没有执行太多的错误检查。您假定对
的调用总是成功的LoadLibrary
- 呼叫约定不匹配。在DLL中使用
,在可执行文件中使用stdcall
register
- 序号不匹配。在DLL中是添加(1)、加载(2)和保存(3)。在可执行文件中添加(3)、加载(1)和保存(2)
- 每次从DLL调用函数时,都会加载和卸载DLL。这意味着每次卸载DLL时,DLL中保存您的状态的全局变量都会丢失
external
关键字。这将通过删除对LoadLibrary
、GetProcAddress
等的所有调用来大大简化代码。如果需要运行时链接,您可以稍后使用delayed
关键字添加它 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.