我调用sakemail做的dll时,有参数错误。不知是dll文件的错还是调用时出错?急!!!200分送上!!!(200分)

  • 主题发起人 主题发起人 scorpions
  • 开始时间 开始时间
S

scorpions

Unregistered / Unconfirmed
GUEST, unregistred user!
我调用sakemail做的dll时,有参数错误。不知是dll文件的错还是调用时出错?
Tsakmsglist在哪释放??

我的dll:
library pd1;
uses
sharemem,
forms,
sakemail,
SysUtils,
Classes;

var
pop:Tsakpop;
list:Tsakmsglist;
procedure connect1(host1,user1,passwd1:pchar;
var newmail1,mail1:integer);stdcall;
begin
try
pop:=Tsakpop.Create(Application);
list:=Tsakmsglist.Create(Application);
pop.Host:=host1;
pop.UserId:=user1;
pop.Passwd:=passwd1;
pop.Connect ;
pop.Login ;
newmail1:=pop.Init ;
mail1:=pop.MsgsCount ;
pop.RetrieveAllMessages(list);
pop.Quit ;
finally
pop.free;

end;
end;
procedure show1(s:integer;var from1,subject1,date1,msgid1,text1,aname:pchar);
stdcall;
var
i:integer;
msg:Tsakmsg;
begin
msg:=list.Items;
from1:=pchar(msg.From );
subject1:=pchar(msg.Subject);
date1:=pchar(msg.Date);
msgid1:=pchar(msg.MessageId );
text1:=pchar(msg.Text.Text);
if msg.AttachedFiles.Count >0 then
begin
for i:=0 to msg.AttachedFiles.Count-1 do
aname:=pchar(msg.AttachedFiles.FileName );
end;
end;
procedure del1(s:integer); stdcall;
begin
list.Delete(s);
end;
exports
connect1,
show1,
del1;


begin
end.
调用dll:
unit pe1;

interface

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

type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Button1: TButton;
Edit6: TEdit;
Button2: TButton;
Button3: TButton;
Edit7: TEdit;
Edit8: TEdit;
Edit9: TEdit;
Edit10: TEdit;
ComboBox1: TComboBox;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
procedure connect1(host1,user1,passwd1:pchar;
var newmail1,mail1:integer);stdcall;
external'pd1.dll';
procedure show1(s:integer;var from1,subject1,date1,msgid1,text1,aname:pchar);
stdcall;external'p2.dll';
procedure del1(s:integer); stdcall;
external'pd1.dll';
implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
host1,user1,passwd1:pchar;
mail1,newmail1:integer;
begin
host1:=pchar(edit1.Text) ;
user1:=pchar(edit2.Text) ;
passwd1:=pchar(edit3.Text) ;
connect1(host1,user1,passwd1,newmail1,mail1);
edit4.text:=inttostr(newmail1);
edit5.text:=inttostr(mail1);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
s:integer;
begin
s:=strtoint(edit6.text);
del1(s);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
s:integer;
from1,subject1,date1,msgid1,text1,aname:pchar;
begin
s:=strtoint(edit6.text);
show1(s,from1,subject1,date1,msgid1,text1,aname);
edit7.text:=string(from1);
edit8.text:=string(subject1);
edit9.text:=string(date1);
edit10.text:=string(msgid1);
combobox1.Items.Clear ;
combobox1.Items.Text:=string(aname);
memo1.Lines.Text:=string(text1);
end;

end.
 
什么地方报告错误
 
调用时点button3出错,不知是dll,还是调用时参数类型出错。???
 
你有没有跟踪过是哪一句?
以前我用过SAKEMAIL,等我找出以前的程序给你试一下
 
procedure show1(s:integer;var from1,subject1,date1,msgid1,text1,aname:pchar);
stdcall;
var
i:integer;
msg:Tsakmsg;
begin
msg:=list.Items;
from1:=pchar(msg.From );
subject1:=pchar(msg.Subject);
date1:=pchar(msg.Date);
msgid1:=pchar(msg.MessageId );
text1:=pchar(msg.Text.Text);
if msg.AttachedFiles.Count >0 then
begin
for i:=0 to msg.AttachedFiles.Count-1 do
aname:=pchar(msg.AttachedFiles.FileName );
end;
end;
这个过程可能有问题,调用时参数都为nil.
 
我第一次用动态连接库,不知string 和 pchar 相互怎么转换???
 
Pchar(string变量):转成 pchar 格式。相反的忘了,好象是 strpas 什么的。
 
不知动态创建的控件Tsakmsglist在哪释放???
 
对不起,刚才有写事情
1、 pchar实际是一个指向内存的指针,使用前一般要先初始化一下
在调用show1前试着加入下面的语句
new(from1);
new(subject1);
new(date1);
new(msgid1);
new(text1);
new(aname);
从DOS过来的PASCAL程序员也许比较难以理解PCHAR的真正含义、不过用STRING
已经很方便了:)
2、想释放时,list.Destroy就可以了
 
释放用.Destroy 还是 .free ??
动态连接库里一般用pchar,不用string.
我的动态连接库的show1过程的参数类型可能有问题.调用时参数都为nil.
我上次在动态连接库里用string型,参数值都正确,关闭窗体时报错,说参数
类型错误.改为pchar型以后,关闭窗体时不报错,可show1过程变量参数值
都为nil. 调用show1过程时报错.
不知怎么回事???


 
问题可能不仅仅在于PChar和String。
我测试的结果是:第一次connect1的时候,给List赋了值,但等到
Show1的时候,这些值都已经没有了。真是莫名惊诧。
 
那时我动态连接库有大问题了???
 
没有什么大问题,
我已经按照你的程序改过后就可以了
 
改哪里?是哪的错误?请您指点!!!
 
我按您上次说的处使化了可还不行。一调用show1过程就报错。
show1返回的值成了些乱码只类的东西。不知怎么回事???
 
问题解决,但为什么会这样,我还是有点不是很明白:

unit smtp1;
中调用pd1.dll函数原型为:

procedure connect1(host1,user1,passwd1:pchar;
var newmail1,mail1:integer);stdcall;external'pd1.dll';
procedure show1(s:integer;var from1,subject1,date1,msgid1,text1,aname:pchar);stdcall;external'pd1.dll';
procedure del1(s:integer); stdcall;external'pd1.dll';
procedure allocateall1;stdcall;external'pd1.dll';//初始化
procedure destoryall1;stdcall;external'pd1.dll';//释放

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

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
destoryall1;
end;
smtp1.pas其他函数不变。

pd1.pas如下:
library pd1;
uses
sharemem,
forms,
sakpop3,
sakmsg,
SysUtils,
Classes;

var
pop:Tsakpop;
list:Tsakmsglist;

procedure allocateall1;stdcall;
begin
pop:=Tsakpop.Create(Application);
list := Tsakmsglist.create(Application);
end;

procedure destoryall1;stdcall;
begin
pop.free;
list.free;
end;

procedure connect1(host1,user1,passwd1:pchar;
var newmail1,mail1:integer);stdcall;
begin
pop.Host:=host1;
pop.UserId:=user1;
pop.UserPasswd:=passwd1;
pop.Connect ;
pop.Login ;
pop.Init;
newmail1:=pop.NewMsgsCount;
mail1:=pop.MsgsCount ;
pop.RetrieveAllMessages(list);
pop.Quit ;
end;

procedure show1(s:integer;var from1,subject1,date1,msgid1,text1,aname:pchar);
stdcall;
var
i:integer;
msg:Tsakmsg;
attachments:String;
procedure CopyToPChar(var Dest:PChar;Source:String);
begin
GetMem(Dest,Length(Source) + 1);
StrPCopy(Dest,Source);
Dest[Length(Source)] := #0;
end;
begin
msg:=list.Items;

CopyToPChar(from1,msg.From);
CopyToPChar(subject1,msg.Subject);
CopyToPChar(date1,msg.date);
CopyToPChar(msgid1,msg.messageid);
CopyToPChar(text1,msg.text.text);

attachments := '';
if msg.AttachedFiles.Count >0 then
begin
for i:=0 to msg.AttachedFiles.Count-1 do
attachments:=attachments + msg.AttachedFiles.FileName;
end;

CopyToPChar(aName,attachments);
end;

procedure del1(s:integer); stdcall;
begin
list.Delete(s);
end;

exports
connect1,
show1,
del1,
allocateall1,
destoryall1;

begin
end.

你试试看。





 
多人接受答案了。
 
对不起又来晚了,
1、destroy不会自动释放内存,用free
2、再次说明PCHAR是个指针(不过上次回答似乎不得要领)、看看下面STRPCOPY的解释

Copies a Pascal string to a null-terminated string.

Unit

Sysutils

Category

string handling routines (null-terminated)

function StrPCopy(Dest: PChar; const Source: string): PChar;

Description

StrPCopy copies a Pascal-type string Source into a null-terminated string Dest. It returns a pointer to Dest.

StrPCopy does not perform any length checking.

The destination buffer must have room for at least Length(Source)+1 characters.

相关的可查STRPAS,STRPLCOPY等

3、DreamTiger兄的SAKEMAIL版本和我的好象不一样,我改了一下

程序部分:
unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
Edit8: TEdit;
Edit9: TEdit;
Edit10: TEdit;
Memo1: TMemo;
ComboBox1: TComboBox;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
procedure connect1(host1,user1,passwd1:pchar;
var newmail1,mail1:integer);stdcall;
external'pd1.dll';
procedure show1(s:integer;var from1,subject1,date1,msgid1,text1,aname:pchar);
stdcall;external'pd1.dll';
procedure del1(s:integer); stdcall;
external'pd1.dll';
procedure allocateall1; stdcall;
external'pd1.dll';

procedure destoryall1; stdcall;
external'pd1.dll';

implementation
//uses unit2;
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
host1,user1,passwd1:string;
mail1,newmail1:integer;
begin
host1:=pchar(edit1.Text) ;
user1:=pchar(edit2.Text) ;
passwd1:=pchar(edit3.Text) ;
connect1(pchar(host1),pchar(user1),pchar(passwd1),newmail1,mail1);
edit4.text:=inttostr(newmail1);
edit5.text:=inttostr(mail1);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
s:integer;
begin
s:=strtoint(edit6.text);
del1(s);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
s:integer;
from1,subject1,date1,msgid1,text1,aname:pchar;
begin
s:=strtoint(edit6.text);
show1(s,from1,subject1,date1,msgid1,text1,aname);
edit7.text:=string(from1);
edit8.text:=string(subject1);
edit9.text:=string(date1);
edit10.text:=string(msgid1);
combobox1.Items.Clear ;
combobox1.Items.Text:=string(aname);
memo1.Lines.Text:=string(text1);
end;



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

procedure TForm1.FormDestroy(Sender: TObject);
begin
destoryall1;
end;

end.unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
Edit8: TEdit;
Edit9: TEdit;
Edit10: TEdit;
Memo1: TMemo;
ComboBox1: TComboBox;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
procedure connect1(host1,user1,passwd1:pchar;
var newmail1,mail1:integer);stdcall;
external'pd1.dll';
procedure show1(s:integer;var from1,subject1,date1,msgid1,text1,aname:pchar);
stdcall;external'pd1.dll';
procedure del1(s:integer); stdcall;
external'pd1.dll';
procedure allocateall1; stdcall;
external'pd1.dll';

procedure destoryall1; stdcall;
external'pd1.dll';

implementation
//uses unit2;
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
host1,user1,passwd1:string;
mail1,newmail1:integer;
begin
host1:=pchar(edit1.Text) ;
user1:=pchar(edit2.Text) ;
passwd1:=pchar(edit3.Text) ;
connect1(pchar(host1),pchar(user1),pchar(passwd1),newmail1,mail1);
edit4.text:=inttostr(newmail1);
edit5.text:=inttostr(mail1);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
s:integer;
begin
s:=strtoint(edit6.text);
del1(s);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
s:integer;
from1,subject1,date1,msgid1,text1,aname:pchar;
begin
s:=strtoint(edit6.text);
show1(s,from1,subject1,date1,msgid1,text1,aname);
edit7.text:=string(from1);
edit8.text:=string(subject1);
edit9.text:=string(date1);
edit10.text:=string(msgid1);
combobox1.Items.Clear ;
combobox1.Items.Text:=string(aname);
memo1.Lines.Text:=string(text1);
end;



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

procedure TForm1.FormDestroy(Sender: TObject);
begin
destoryall1;
end;

end.unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
Edit8: TEdit;
Edit9: TEdit;
Edit10: TEdit;
Memo1: TMemo;
ComboBox1: TComboBox;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
procedure connect1(host1,user1,passwd1:pchar;
var newmail1,mail1:integer);stdcall;
external'pd1.dll';
procedure show1(s:integer;var from1,subject1,date1,msgid1,text1,aname:pchar);
stdcall;external'pd1.dll';
procedure del1(s:integer); stdcall;
external'pd1.dll';
procedure allocateall1; stdcall;
external'pd1.dll';

procedure destoryall1; stdcall;
external'pd1.dll';

implementation
//uses unit2;
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
host1,user1,passwd1:string;
mail1,newmail1:integer;
begin
host1:=pchar(edit1.Text) ;
user1:=pchar(edit2.Text) ;
passwd1:=pchar(edit3.Text) ;
connect1(pchar(host1),pchar(user1),pchar(passwd1),newmail1,mail1);
edit4.text:=inttostr(newmail1);
edit5.text:=inttostr(mail1);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
s:integer;
begin
s:=strtoint(edit6.text);
del1(s);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
s:integer;
from1,subject1,date1,msgid1,text1,aname:pchar;
begin
s:=strtoint(edit6.text);
show1(s,from1,subject1,date1,msgid1,text1,aname);
edit7.text:=string(from1);
edit8.text:=string(subject1);
edit9.text:=string(date1);
edit10.text:=string(msgid1);
combobox1.Items.Clear ;
combobox1.Items.Text:=string(aname);
memo1.Lines.Text:=string(text1);
end;



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

procedure TForm1.FormDestroy(Sender: TObject);
begin
destoryall1;
end;

end.

DLL部分:
library pd1;
uses
forms,
sakemail,
SysUtils,
Classes;

var
pop:Tsakpop;
list:Tsakmsglist;

procedure allocateall1;stdcall;
begin
pop:=Tsakpop.Create(nil);
list := Tsakmsglist.create(nil);
end;

procedure destoryall1;stdcall;
begin
pop.free;
list.free;
end;

procedure connect1(host1,user1,passwd1:pchar;
var newmail1,mail1:integer);stdcall;
begin
pop.Host:=pchar(host1);
pop.UserId:=pchar(user1);
pop.Passwd:=pchar(passwd1);
pop.Connect ;
pop.Login ;
pop.Init;
newmail1:=pop.init;
mail1:=pop.MsgsCount ;
pop.RetrieveAllMessages(list);
pop.Quit ;
end;

procedure show1(s:integer;var from1,subject1,date1,msgid1,text1,aname:pchar);
stdcall;
var
i:integer;
msg:Tsakmsg;
attachments:String;
procedure CopyToPChar(var Dest:PChar;Source:String);
begin
GetMem(Dest,Length(Source) + 1);
StrPCopy(Dest,Source);
Dest[Length(Source)] := #0;
end;
begin
msg:=list.Items;

CopyToPChar(from1,msg.From);
CopyToPChar(subject1,msg.Subject);
CopyToPChar(date1,msg.date);
CopyToPChar(msgid1,msg.messageid);
CopyToPChar(text1,msg.text.text);

attachments := '';
if msg.AttachedFiles.Count >0 then
begin
for i:=0 to msg.AttachedFiles.Count-1 do
attachments:=attachments + msg.AttachedFiles.FileName;
end;

CopyToPChar(aName,attachments);
end;

procedure del1(s:integer); stdcall;
begin
list.Delete(s);
end;

exports
connect1,
show1,
del1,
allocateall1,
destoryall1;

begin
end.

4、要显示文本内容需要使用HTML控件
5、不好意思怎么晚回复你的帖子,不过事情多多:)
 
后退
顶部