2012-01-16 17 views
5

Mam źródło starszego projektu i muszę zmienić małe rzeczy, ale mam duże kłopoty, ponieważ mam tylko delphi 2010, aby to zrobić.Problemy z ciągami migracyjnymi Delphi 3 do Delphi 2010

Jest rekord zdefiniowane:

bbil = record 
    path : string; 
    pos: byte; 
    nr: Word; 
end; 

później definicja ta służy do odczytu z pliku:

b_bil: file of bbil; 
pbbil: ^bbil; 
l_bil : tlist; 

while not(eof(b_bil)) do 
    begin 
    new(pbbil); 
    read(b_bil, pbbil^); 
    l_bil.add(pbbil); 
    end 

Podstawowym problemem jest to, że kompilator nie akceptuje typu „string” w rekord, ponieważ chce "finalizacji". Próbowałem więc zmienić "ciąg" na "string [255]" lub "shortstring". W ten sposób aplikacja odczytuje plik, ale zawiera niewłaściwą treść.

Moje pytanie brzmi: jak przerobić starego typu „string” z których pliki zostały zapisane do „nowych” typów w Delphi 2010.

Próbowałem już wiele np "{$ H-}". Dodanie tylko jednego znaku więcej w pokazach rekordów, plik jest poprawny, ponieważ plik jest prawie poprawny, ale skrócono o jeden znak więcej każdego zbioru danych - długość długości bajty + 255 znaków wydaje się być poprawna, ale skrót nie pasuje.

+0

Korzystanie AnsiString w wyniki definicji rekordu również w erraty kompilatora: "finalizacja potrzebnego bbil". Skracając te AnsiString w ten sposób "pfad: AnsiString [255];" nie działa również: "; oczekiwano, ale [znaleziono". Co prawdopodobnie potrzebuję to ShortAnsiString? – rseffner

+2

IMO Twój kod również nie powinien się kompilować w Delphi 3; spróbuj 'path: array [0..N] z AnsiChar;', gdzie N jest trochę stałą, może 255. – kludg

+2

Zrób tak, jak mówi David, zadeklaruj ciąg jako 'ShortString'. Aby dopasować rekord, spróbuj dyrektywy dotyczącej spakowanego rekordu, jeśli to pomaga. Aby kod ten działał w D3, musiano użyć dyrektywy {$ H-}. –

Odpowiedz

5

Eek! Wygląda na to, że twój kod albo wcześniejsza wersja, albo nie używa długich łańcuchów. Jeśli chcesz uzyskać takie samo zachowanie, jak w starym Delphi, musisz wymienić string na ShortString.

Widzę, że już to wypróbowałeś i zgłoś, że się nie udało. To naprawdę jedyne wytłumaczenie, które ma dla mnie sens, ponieważ wszystkie inne typy ciągów są w zasadzie wskaźnikami, więc jedynym sposobem, w jaki mógł pracować read, jest ShortString. Migracja, którą próbujesz, jest ogromna i prawdopodobnie masz ogromną liczbę kłopotliwych problemów.

@LU RD dobrze wskazuje na komentarze, że układ rekordów może różnić się między wersjami Delphi, ponieważ nie używasz tablicy packed. Możesz zbadać układ rekordów za pomocą dwóch wersji Delphi, które masz pod ręką. Musisz ustalić, że rozmiar rekordów jest zgodny między wersjami i że wyrównania do pól również są zgodne.

Na podstawie poniższych komentarzy, dodanie bajtów dopełnienia między pozycjami i nr spowoduje rozwiązanie problemów.

bbil = record 
    path : string; 
    pos: byte; 
    _pad: byte; 
    nr: Word; 
end; 

Można również osiągnąć ten sam efekt poprzez ustawienie $ALIGN kompilator {$ALIGN ON} która byłaby jak sądzę bym go o rzeczy.

Na dłuższą metę naprawdę powinieneś uciec od krótkich łańcuchów, kodowania ANSI, bezpośredniego mapowania między twoimi wewnętrznymi zapisami i twoimi plikami danych i tak dalej. Na krótką metę lepiej będzie, jeśli uda ci się uzyskać tę samą wersję Delphi, która została użyta do zbudowania tego kodu i użycia go. Spodziewałbym się, że ten problem będzie tylko czubkiem góry lodowej.

+0

David, myślę, że rada "ShortString" jest poprawna, tylko rozmiar rekordu musi pasować. Dyrektywa wyrównania może rozwiązać tę lub być może deklarację zapakowanego rekordu. –

+0

Używanie ShortString jako zamiennika "String" w zestawie rekordów było jedną z pierwszych rzeczy, które zrobiłem. Ale działa niezgodnie z oczekiwaniami, wszystkie przeczytane datarecords były koszmarne ;-(Muszę teraz przeczytać o "pakowanej dyrektywie rekordowej" - bo nie wiem. – rseffner

+1

Po prostu zadeklaruj typ jako "zapakowany rekord" zamiast "rekordu". usunie linie trasowania wykonane przez kompilator Aby zobaczyć rozmiar rekordu, spróbuj użyć 'SizeOf (bbil)'. –

2

Wystarczy pamiętać:

"string" <> "string [255]" <> "shortstring" <> AnsiString

Powrót w starych DOS/Turbo Pascal dni "struny" były rzeczywiście ogranicza się do 255 znaków. W dużej mierze dlatego, że pierwszy bajt zawierał długość ciągu, a bajt może mieć tylko wartość od 0 do 255.

To już nie jest problem we współczesnych wersjach Delphi.

"ShortString" jest typem starego typu ciąg DOS/Pascal.

"LongString" to domyślny typ ciągu od długiego czasu (w tym Borland Delphi 2006, którego używam obecnie w większości prac produkcyjnych). Od Delphi 3 .. Delphi 2009, LongStrings posiadanych 8-bitowych znaków, i były ograniczone tylko przez dostępną pamięć. Od Delphi 3 .. Delphi 2009, "LongStrings" były synonimami "AnsiStrings".

Najnowsze wersje Delphi (Delphi 2009 i nowsze wersje, w tym nowe Delphi XE2) są teraz domyślnie wielobajtowe ciągi "WideString" Unicode. WideStrings, podobnie jak AnsiStrings, są również efektywnie "nieograniczone" w maksymalnej długości.

tym artykule opisano bardziej szczegółowo:

http://delphi.about.com/od/beginners/l/aa071800a.htm

PS: Rozważ użycie "sizeof (bbil)" i "Packed" zapisów binarnych.

+1

W terminologii Delphi długie łańcuchy odnoszą się zarówno do AnsiString, jak i UnicodeString, przy czym ten ostatni jest nowym typem łańcucha wprowadzonym w D2009. I WideString jest znowu inny, jest opakowaniem wokół COM BSTR. –

+2

@rseffner - Terminologia może być myląca. Głównie wina Microsoftu. Proszę spojrzeć na linki, które cytowałem (w szczególności na artykuł "about.com"), aby zrozumieć ciągi znaków. I eksperymentuj z "sizeof()", aby rozwiązać problemy związane z pakowaniem i wyrównaniem z twoimi zapisami binarnymi. – paulsm4

+1

Terminologia jest całkowicie jasna i nie ma nic wspólnego ze stwardnieniem rozsianym. Dany język jest tworzony przez Embarcadero. Mój poprzedni komentarz próbował skierować cię do naprawienia różnych błędów w twojej odpowiedzi. W obecnej formie jest to raczej niedokładne. –

0

Może coś przeoczyłem, ale, jak widzę, twój kod delphi 3 również jest uszkodzony. Spróbuj ustalić rozmiar rekordzie:

bbil = record 
    path : string; 
    pos: byte; 
    nr: Word; 
end; 

ścieżki (coś między 1 a 256 - jeden bajt na długości spoczynkowej dla danych), pos (1 bajt), nr (2 bajty), dzięki czemu dane rekordu rozmiar zmienia się od 1 + 1 + 2 = 4 bajty do 256 + 1 + 2 = 259 bajtów. W takiej sytuacji w każdym razie otrzymasz śmieci z pliku, ponieważ twój program nie może teraz odczytać liczby bajtów przed odczytaniem danych. Proponuję poprawić rekord tak, że ciąg jest stałym rozmiarze, jak:

path : ShortString[255]; 

Następnie będzie można pisać i czytać w porządku zarówno w Delphi 3 i 2010.

+0

Z drugiej strony, delphi 3 nie ma typu shortstring, będziesz musiał zdefiniować go jako ciąg w delphi 3. –

Powiązane problemy