编写DLL时,调用结果正确,但调用完后出错!请看:(20分)

  • 主题发起人 主题发起人 fancy105
  • 开始时间 开始时间
F

fancy105

Unregistered / Unconfirmed
GUEST, unregistred user!
DLL中的函数定义:
{*Get the Version information of the application*}
function GetVersionInfo:String;stdcall;
var
VerInfoSize, VerValueSize, Dummy : DWORD;
VerInfo : Pointer;
VerValue : PVSFixedFileInfo;
V1,V2,V3,V4:word;
begin
VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), Dummy);
GetMem(VerInfo, VerInfoSize);
GetFileVersionInfo(PChar(ParamStr(0)), 0, VerInfoSize, VerInfo);
VerQueryValue(VerInfo, '/', Pointer(VerValue), VerValueSize);
With VerValue^ do
begin
V1 := dwFileVersionMS shr 16;
V2 := dwFileVersionMS and $FFFF;
V3 := dwFileVersionLS shr 16;
V4 := dwFileVersionLS and $FFFF;
end;
Result:=IntToStr(V1)+'.'+IntToStr(V2)
+'.'+IntToStr(V3) + '.'+ IntToStr(V4);
FreeMem(VerInfo, VerInfoSize);
end;

exports
CreateShadeWindow,
GetVersionInfo;

begin
end.

调用程序:
unit u_frmTestFace;

interface

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

type
TGetVersionInfo=function:String;stdcall;
TCreateShadeWindow=function(AHandle:THandle;
x1,y1,x2,y2,fx,fy:integer):Boolean;stdcall;
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure SetWindowStyle;
procedure GetApplicationVersion;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.SetWindowStyle;
var
AHandle:THandle;
CreateShadeWindow:TCreateShadeWindow;
begin
AHandle:=LoadLibrary('FaceFunc.dll');
if AHandle<>0 then
begin
@CreateShadeWindow:=GetProcAddress(AHandle,'CreateShadeWindow');
if @CreateShadeWindow<>nil then
CreateShadeWindow(Handle,20,30,214,123,10,10);
end;
FreeLibrary(AHandle);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
//SetWindowStyle;
end;

procedure TForm1.GetApplicationVersion;
var
AHandle:THandle;
GetVersionInfo:TGetVersionInfo;
begin
AHandle:=LoadLibrary('FaceFunc.dll');
if AHandle<>0 then
begin
@GetVersionInfo:=GetProcAddress(AHandle,'GetVersionInfo');
if @GetVersionInfo<>nil then
ShowMessage(GetVersionInfo);
FreeLibrary(AHandle);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
GetApplicationVersion;
end;

end.
 
Delphi 做DLL不要用STRING作为数据返回类型,windows的其他程序是不认的,用PCHAR吧,这样你的程序应该就没有问题了
 
dll不能用string传递,用Pchar或固定长度字符串就可以了
 
procedure GetVersionInfo(var result:pchar);stdcall;
var
VerInfoSize, VerValueSize, Dummy : DWORD;
VerInfo : Pointer;
VerValue : PVSFixedFileInfo;
V1,V2,V3,V4:word;
begin
VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), Dummy);
GetMem(VerInfo, VerInfoSize);
GetFileVersionInfo(PChar(ParamStr(0)), 0, VerInfoSize, VerInfo);
// VerQueryValue(VerInfo, '/', Pointer(VerValue), VerValueSize);
With VerValue^ do
begin
V1 := dwFileVersionMS shr 16;
V2 := dwFileVersionMS and $FFFF;
V3 := dwFileVersionLS shr 16;
V4 := dwFileVersionLS and $FFFF;
end;
Result:=pchar(IntToStr(V1)+'.'+IntToStr(V2)
+'.'+IntToStr(V3) + '.'+ IntToStr(V4));
FreeMem(VerInfo, VerInfoSize);
end;

exe中
1、 TGetVersionInfo=procedure(var result:pchar);stdcall;
2、
@GetVersionInfo:=GetProcAddress(AHandle,'GetVersionInfo');
if @GetVersionInfo<>nil then
begin
GetVersionInfo(str);
showmessage(str);
end;
FreeLibrary(AHandle);

可以了,没报错。
 
uses sharemem;

调用及dll中都要第一个uses。
 
可是为什么调用结果是对的?即显示对话框并显示正确和版本号,但确定后就出错。
 
http://www.delphibbs.com/delphibbs/dispq.asp?LID=1723880
 
加入ShareMem单元后,调用正确,确定对话框后也没问题,
但关闭窗口就出错了!是Runtime Error!
 
在DLL中使用List(TStringList类型)作地址传递参数传入,写入值后再传出。
但在EXE程序中读出的List.Count是正确的,但无法读出它的值,在读它的值
时出现内存地址错误·! 怎么办? 该不会是将List中的每个值又用PChar传
出吧?
 
如果String不是很长的话,用ShortString代替也可以
 
ShotString又有什么区别?
 
多人接受答案了。
 
后退
顶部