我试图在 Tqueue 中存储指向记录的指针,然后稍后将指针出队并提取数据,但我对指针感到困惑并不断收到“抽象错误”
任何人都可以看看我做错了什么并建议我正确的解决方案吗?
(顺便说一句,最初我没有^,但后来意识到我的错误,但很惊讶它仍然给出了错误)
记录保存发送到 smtp 服务器的电子邮件数据,它使用 TstringList 保存正文的每一行,使用另一个 TstringList 保存每个附件文件名
这是用于存储电子邮件数据的记录结构
TPtrEmailData = ^TEmailDataRec;
TEmailDataRec = record
ToAddr : string; //one email address
CcAddr : string; //addresses delimitated by semicolons
BccAddr : string; //addresses delimitated by semicolons
Subject : String;
Body : TStrings; //each string contains one line of the body
attachments: TStrings;//each string contains a filename
end;
创建我使用的记录
function TFrmSendEmail.CreateNewEmailRec: TPtrEmailData;
var
EmailRecPtr : TPtrEmailData;
begin
new(EmailRecPtr); //make a new record
EmailRecPtr^.Body := Tstrings.Create ;
EmailRecPtr^.attachments := Tstrings.create;
result := EmailRecPtr ;
end;
并在出队后释放它们,我使用
procedure TFrmSendSllSmtptEmail.DestroyEmailRec(EmailRecPtr : TPtrEmailData);
//frees memory for the Tstrings and then frees the record
begin
freeandnil(EmailRecPtr^.Body); //free one Tstringlist
FreeAndNil(EmailRecPtr^.attachments); //and the other
FreeAndNil(EmailRecPtr ); //now free the precord pointer
end;
当我使用以下命令将新记录指针放入队列中时,会调用 CreateNewEmailRec,传入包含正文和附件的备忘录和列表框。这是我收到错误的地方。
procedure TFrmSendEmail.AddToEmailQueue(ToAddr, CCAddr,
BccAddr,Subject:String;
Body: Tmemo; Attachments: TListBox);
var
i : integer;
s : string;
EmailRecPtr : TPtrEmailData;
begin
EmailRecPtr := CreateNewEmailRec; //allocate memory
//deallocated in RemoveFromEmailQueue
EmailRecPtr^.ToAddr := ToAddr;
EmailRecPtr^.CCAddr := CCAddr;
EmailRecPtr^.BccAddr := BccAddr;
for I := 0 to Attachments.Count - 1 do
begin
s := Attachments.Items[i];
EmailRecPtr^.attachments.add(s ); <---- !!! get abstract error here
end;
for I := 0 to Body.lines.Count - 1 do
begin
s := Body.lines[i];
EmailRecPtr^.Body.Add(s) ;
end;
EmailQueue.Enqueue(EmailRecPtr );
end;
当我将指针出列以使用中的数据时,会调用 DestroyEmailRec
procedure TFrmSendEmail.RemoveFromEmailQueue(var ToAddr,
CCAddr,
BccAddr,
Subject: String;
var Body,
Attachments: TStringlist);
var
EmailRecPtr :TPtrEmailData;
i : integer;
s : string;
begin
if EmailQueue.Count > 0 then
begin
Body.Clear;
Attachments.Clear;
EmailRecPtr := EmailQueue.Dequeue; //get pointer to next record
ToAddr := EmailRecPtr^.ToAddr; //populate procedure parameters
CCAddr := EmailRecPtr^.CCAddr;
BccAddr := EmailRecPtr^.BccAddr;
for EmailRecPtr^.attachments.Count - 1 do
begin
s := EmailRec^.attachments[i];
Attachments.Add(s) ;
end;
for I := 0 to EmailRecPtr ^.Body.Count - 1 do
begin
s := EmailRecPtr ^.Body[i];
Body.Add(s);
end;
DestroyEmailRec(EmailRecPtr); //release memory
end;
对RemoveFromEmailQueue的调用传递了几个创建的TStringLists
TheBody := Tstringlist.Create ;
TheAttachments := Tstringlist.create;
try
RemoveFromEmailQueue(ToAddr, CCAddr, BccAddr, Subject,TheBody,TheAttachments);
// do stuff with the data;
finally
TheBody.Free;
TheAttachments.Free;
end;
哦,队列被声明为
var
EmailQueue : Tqueue<TPtrEmailData>;
最佳答案
您收到“抽象错误”,因为您使用了抽象对象 (TStrings
)!在 TFrmSendEmail.CreateNewEmailRec
方法中,将 TStrings
替换为 TStringList
:
function TFrmSendEmail.CreateNewEmailRec: TPtrEmailData;
begin
new(result); //make a new record
Result^.Body := TStringList.Create ;
Result^.attachments := TStringList.create;
end;
此外,您无法使用 FreeAndNil
释放记录!所以你释放记录的方法应该是这样的
procedure TFrmSendSllSmtptEmail.DestroyEmailRec(EmailRecPtr : TPtrEmailData);
//frees memory for the Tstrings and then frees the record
begin
EmailRecPtr^.Body.Free; //free one Tstringlist
EmailRecPtr^.attachments.Free; //and the other
Dispose(EmailRecPtr); //now free the precord pointer
end;
关于delphi - 在 Delphi 的 Tqueue 中存储记录指针的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26913953/