请问以下调用DLL的代码哪里错了?(20分)

  • 主题发起人 主题发起人 TENTODBV
  • 开始时间 开始时间
T

TENTODBV

Unregistered / Unconfirmed
GUEST, unregistred user!
//以下是调用DLL的主程序代码
unit MainUnit;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TOutFunc=function(AHandle:THandle;ACaption:string):string;stdcall;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
LibHandle:THandle;
OutFunc:TOutFunc;
begin
LibHandle:=LoadLibrary('LoadDll.dll');
try
if LibHandle=0 then ;
@OutFunc:=GetProcAddress(LibHandle,'OutFunc');
if not (@OutFunc=nil) then
//Form1.Caption:=OutFunc(Application.Handle,'abc');//这行代码出错
Form1.Caption:=OutFunc(Application.Handle,Form1.Caption+'abc');//为何这行代码又可以呢?
finally
FreeLibrary(LibHandle);
end;
end;

end.




//以下是DLL工程源代码
library LoadDLL;

uses
SysUtils,
Classes,
DLLFrm in 'DLLFrm.pas' {Form1};
exports
OutFunc;

{$R *.res}

begin
end.

//以下是DLL中模式窗体的代码
unit DLLFrm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;


type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Calendar1DblClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
bOK:boolean;
end;


function OutFunc(AHandle:THandle;ACaption:string):string;stdcall;

implementation

{$R *.dfm}

function OutFunc(AHandle:THandle;ACaption:string):string;
var
Form1: TForm1;
begin
Application.Handle:=AHandle;
try
Form1:=TForm1.Create(Application);
Form1.Caption:=ACaption;
Form1.ShowModal;
if Form1.bOK then
Result:=ACaption;
finally
Form1.Free;
end;
end;

procedure TForm1.Calendar1DblClick(Sender: TObject);
begin
Close;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
bOK:=true;
Close;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Close;
end;

end.
 
stdcall后面加上。DLL的名字就可以拉
 
可能是Sharemem忘加了吧
 
function OutFunc(AHandle:THandle;ACaption:string):string;stdcall
改成
Acaption:pchar
 
To SmallGhost
试过加上Sharemem 还是不行。

To shen481900
如何stdcall后面加上DLL的名字?是加在DLL里还是主程序里?
 
看一下这个代码:
www.my2000.biz/temp1/DLL-2.rar
 
有external和export?
 
请在我的代码的基础上,指出应该怎样改。
 
这个代码完全没错,我都运行通过了,请问楼主是报什么错啊?
 
我是把procedure Calendar1DblClick(Sender: TObject);的事件去掉了,没写上去所以运行时没报任何的错.
 
Calendar1 的代码是我删除的时候没删干净,去掉即可,应该没影响。

出错表现为单击DLL模式窗体的OK按钮(按钮1)返回主窗口时提示
Access Violation at address 00403E1C in module LOADDLLTEST.EXE.Read of address 012426C0.
LOADDLLTEST.EXE是主程序
 
不要用string作传递参数和函数返回值,最好用PChar。
或者将ShareMem加到uses部分的第一个位置。
 
'abc' 是一個常量字符串
Form1.Caption+'abc' 系統動態申請分配一個新的字符串
區別是在這吧
 
还是使用包PACKAGE吧
 
我在主程序单元的uses子句的开头加入ShareMem后,单击DLL模式窗体的OK按钮(按钮1)返回主窗口时就没有出错提示了。(我原来只在DLL中加入ShareMem,而没有在主程序单元的uses加入ShareMem,结果单击DLL模式窗体的OK按钮(按钮1)返回主窗口时就出错)。

但是出现新的问题,我为主窗口添加一个关闭按钮,执行代码只有一行:Close。单击该按钮时程序出错。这应该是加入ShareMem后造成的。请问该如何解决?
 
ShareMem应该加在主程序和DLL的工程文件的uses子句的开头,不是加在单元文件中
 
我遇到过这种情况,在加入sharemem后,关闭程序的时候会报内存冲突,通过跟踪address
cpu在执行到某内存地址时指针紊乱,怀疑是delphi固有的问题,可能只有将dll函数返回值改为pchar或shortstring 类型

期待更好的答案
 
to weiwei81123
你说得对,指出了问题所在。我错在把ShareMem加到主程序单元文件的uses字句了,改为把ShareMem加到主程序工程文件的uses字句就可以了。
 
多人接受答案了。
 

Similar threads

I
回复
0
查看
701
import
I
I
回复
0
查看
690
import
I
I
回复
0
查看
777
import
I
I
回复
0
查看
756
import
I
后退
顶部