delphi - 在 Delphi 的 Tqueue 中存储记录指针的正确方法是什么

标签 delphi pointers queue record

我试图在 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/

相关文章:

c++ - std::queue 初始化为 NULL

python - 使用 Tkinter 正确完成线程化(有或没有队列)

delphi - 修改exe资源中的字符串

c - 如何拥有一个使用指针 ptr 来读取和打印有关书籍结构的内容的程序?

java - 在 Java 中不使用 .size() 的环形缓冲区的lush() 和 isEmpty() 方法

c++ - 对对象使用 new

data-structures - 优先队列 VS 队列

arrays - 数组类型赋值如何工作?

performance - 计算例程的速度?

Delphi WebSphere MQ 远程连接