2009-07-04 4 views
5

Ich versuche, eine Zeichenfolge in einen TStream zu konvertieren. Mein Code unten gibt mir eine "Abstract Error" Nachricht auf der CopyFrom Linie. Ich bin hier gegen eine Mauer, irgendwelche Ideen, wie man das löst?String zu TStream

Antwort

8

AStream als OUT-Parameter deklariert wird, was bedeutet, dass es nicht am Anfang des Verfahrens zugeordnet ist, und das Verfahren ist verantwortlich einen richtigen Wert zuzuweisen es.

Wenn ich Ihren Code richtig interpretiere, sollten Sie OUT weglassen und sicherstellen, dass AStream beim Aufruf der Routine korrekt instanziiert wird.

Etwas mehr Code, der den Aufruf von StringToStream zeigt, kann einige weitere Hinweise geben.

+0

Nun, AStream * ist eindeutig zugewiesen, wenn er einen abstrakten Fehler erhält, wenn er eine Methode aufruft Es ist wahrscheinlich als ein TStream anstatt anstelle einer Nachfahrklasse instanziiert. –

+1

Sie haben Recht, und da die tatsächliche Deklaration des Wertes für AStream genau TStream sein muss (sonst würde der Compiler beschweren), gibt es eine hohe Wahrscheinlichkeit, dass es ist eigentlich eine Instanz des abstrakten TStream anstelle einer geerbten Klasse. Aber abgesehen davon ist es immer noch keine weise Entscheidung, es zu einem Out-Parameter zu machen. –

+0

Danke an alle, die Hilfe angeboten haben. Ich habe sie nur mit einem TStream angerufen. Englisch: www.mjfriendship.de/en/index.php?op...39&Itemid=32 Was ich jetzt erkenne, ergibt wenig Sinn: Ich habe die Prozedur mit einem TMemoryStream aufgerufen und die Prozedur auf (rem (out): prozedur StringToStream (const AString: string; AStream: TMemoryStream); var SS: TStringStream; beginne SS: = TStringStream.Create (AString); versuchen SS.Position: = 0; AStream.CopyFrom (SS, SS.Size); schließlich SS.Free; Ende; Ende; Dies scheint das Problem gelöst zu haben. Nochmals, vielen Dank! –

6

CopyFrom ruft ReadBuffer auf, der Read aufruft, und Read wird als Abstract deklariert. Welche Art von Stream übergibst du an AStream? Wenn Sie Read nicht implementieren, erhalten Sie dort einen abstrakten Fehler. (Und der Compiler sollte Ihnen eine Warnung, wenn Sie es instanziiert.)

+0

Genau. Der AStream, der als ein TStream deklariert ist, ruft die Read-Methode der Basisklasse auf. Er müsste eine Klasse (TStream) angeben, die die read-Methode implementiert. – yozey

+5

Nein, Yozey, das * als * TStream deklariert wird, ist nicht das, was bewirkt, dass die abstrakte Funktion aufgerufen wird. Die Funktion ist virtuell. Die abstrakte Funktion wird aufgerufen, weil ein tatsächliches TStream-Objekt übergeben wurde (oder ein anderer Nachfolger, der diese Funktion noch nicht überschrieben hat. –

4

AStream erklären, da es für mich falsch aussieht. Versuchen Sie, das Problem zu beheben.

Wenn das nicht hilft, hier ist die Funktion, die ich verwenden:

procedure StringToStream(Stream: TStream;const S: String); 
begin 
Stream.Write(Pointer(S)^, length(S)); 
end; 
6

Das folgende Verfahren sollte excactly tun, was Sie suchen. Bitte beachten Sie, dass Ihre Verwendung von AStream dafür verantwortlich ist, die in diesem Verfahren erstellte Instanz freizugeben. Es ist vollkommen in Ordnung, die Elternklasse (in diesem Fall tStream) und nicht den spezifischen Nachkommen zurückzugeben.

procedure StringToStream(const AString: string; out AStream: TStream); 
begin 
    AStream := TStringStream.Create(AString); 
end; 

Sie können dies auch als eine Funktion Code:

Function StringToStream(const AString: string): TStream; 
begin 
    Result := TStringStream.Create(AString); 
end;