请指出如下代码错在那里?怎么改?

zyq_123 2003-01-28 09:00:04
主程序:
MenuRec=record
menuid:pchar;
menuname:pchar;
menutxt:pchar;
menut:pchar;
mennts:integer;
menui:integer;
menuf:pchar;
end;
TRMenu = function():MenuRec;

var
Form1: TForm1;
h:HMODULE;
RMenu:TRmenu;
b:PChar;
MenuR:MenuRec;

procedure TForm1.Button1Click(Sender: TObject);
begin
h:=loadlibrary(pchar('C:\DELPHI程序\aaa\dll\project1.dll'));
RMenu:=GetProcAddress(h,'RMenu');
MenuR:=RMenu;
freelibrary(h);
end;

DLL:
type
MenuRec=record
menuid:pchar;
menuname:pchar;
menutxt:pchar;
menut:pchar;
mennts:integer;
menui:integer;
menuf:pchar;
end;
function RMenu:MenuRec;stdcall;
var aa:MenuRec;
begin
aa.menuname:='database2';
aa.menutxt:='database2';
aa.menut:='data';
aa.mennts:=1;
aa.menui:=2;
aa.menuf:='dll1.dll';
result:=aa;
end;

错误:“Access Violation at address 00000000.Read of address 00000000.

”。
...全文
19 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
sunny 2003-01-30
  • 打赏
  • 举报
回复
分都被你分完了,咳!!害我这么辛苦哟!!!!!!!!
好人做到底:)
对于DLL中的大的数据共享,一般就是几种办法:
1.利用内存映射文件来共享;
2.利用DLL在主程序地址空间的性质来共享。(本程序方法)
sunny 2003-01-30
  • 打赏
  • 举报
回复
我就是你QQ中的土匪,现在来瞧瞧!呵呵
你的代码中要改几个地方!
主程序:
PMenuRec=^MenuRec;//定义一个指向记录的指针类型
MenuRec=record
menuid:pchar;
menuname:pchar;
menutxt:pchar;
menut:pchar;
mennts:integer;
menui:integer;
menuf:pchar;
end;
//TRMenu = function():MenuRec;这个函数声明不要,直接用DLL中函数
//声明即可
function RMenu:PMenuRec;stdcall;external 'C:\DELPHI程序
\aaa\dll\project1.dll';
var
Form1: TForm1;
h:HMODULE;
//RMenu:TRmenu;
b:PChar;
MenuR:PMenuRec;

procedure TForm1.Button1Click(Sender: TObject);
begin
h:=loadlibrary(pchar('C:\DELPHI程序\aaa\dll\project1.dll'));
MenuR:=RMenu;//直接用函数名就可以了
b:=MenuR^.menutxt;//这样调用即可!!!!
showmessage(b);
freelibrary(h);
end;
//得到showmessage的消息显示为:'database2';
DLL:
type
PMenuRec=^MenuRec;//定义一个指向记录的指针类型
MenuRec=record
menuid:pchar;
menuname:pchar;
menutxt:pchar;
menut:pchar;
mennts:integer;
menui:integer;
menuf:pchar;
end;
var aa:MenuRec;//动态的数据,声明在外面,避免随着函数调用完毕而删除
//在函数内部声明的变量在函数调用完毕时都是无法访问的,栈数据被栈顶
//指针屏蔽了,这个要注意!!
function RMenu:PMenuRec;stdcall;
begin
aa.menuname:='database2';
aa.menutxt:='database2';
aa.menut:='data';
aa.mennts:=1;
aa.menui:=2;
aa.menuf:='dll1.dll';
result:=@aa;//返回记录的地址,因为这个DLL被映射到主程序的地址空间
//而aa这个变量不会随着函数调用完毕删除,所以这里返回它的地址,可以
//通过地址来访问相应的数据!
end;
ehom 2003-01-28
  • 打赏
  • 举报
回复
除了少了stdcall之外,还要注意一个问题

MenuR:=RMenu;

是对指针的操作,是将MenuR的地址指向RMenu,即对MenuR操作就是操作RMenu,调用freelibrary(h)注销后,即无法获得记录的值!所以应该对记录变量中的值进行赋值!
Billy_Chen28 2003-01-28
  • 打赏
  • 举报
回复
反回的记录集定义操作有问题
ehom 2003-01-28
  • 打赏
  • 举报
回复
TRMenu = function():MenuRec;

=>

TRMenu = function:MenuRec;stdcall;
zyq_123 2003-01-28
  • 打赏
  • 举报
回复
不行啊!关键不在这里,如果记录中只有一个元数就能运行了,超过一个元素就不行了!不知道为什么?
ysai 2003-01-28
  • 打赏
  • 举报
回复
menuid:pchar;
改为
menuid:array[0..255] of char;
试试,全改
zyq_123 2003-01-28
  • 打赏
  • 举报
回复
up

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧