OemToAnsi VS Delphi 2009

0

Witam!

Tak jak w temacie, czemu oni się gryzą?

Napisałem sobie jakiś czas temu aplikację w delphi 7, fajerwerki z nowszych wersji zazwyczaj nie są mi potrzebne bo to prosty program. Jednak chciałem go przekompilować w wersji 2009 ze względu na to że czytałem iż ona pozwala na późniejsze uruchomienie aplikacji na windows 64 bit, na czym mi bardzo zależy.
Ale jak to zwykle bywa pojawił się problem :/ Kompilator nie chce przepuścić tylko jednej funkcji, jednak jest ona kluczowa dla działania programu :( Program wykorzystuje komendy wiersza poleceń, które obsługuję za pomocą pajpów(pipe). Całośc jest ok, jednak problem pojawia się podczas odczytu zwróconego rezultatu. Błąd wywala na funkcji OemToAnsi.

...

var
  ReadPipe, WritePipe : THandle;
  Buffer : PChar;
  BytesRead : DWord;
  ...

...

function ReadResult : PChar;
begin
  repeat
    BytesRead := 0;
    ReadFile(ReadPipe, Buffer[0], ReadBuffer, BytesRead, nil);
    Buffer[BytesRead]:= #0;
    OemToAnsi(Buffer, Buffer); // klapa
    result := Buffer;
  until
    (BytesRead < ReadBuffer);
end;

...

Nie pasują mu typy danych, ja mu zapodaję PChar kiedy on sobie by życzył AnsiChar.

[DCC Error] Main.pas(123): E2010 Incompatible types: 'Char' and 'AnsiChar'

Czy zna ktoś może jakiś sposób żeby sobie z tym poradzić, może istnieje jakaś inna funkcja służąca do tego? Może ktoś z was się już z tym spotkał?

Szukałem o tym na forum i na googlach więc "nie bijcie", jedyne co znalazłem to podobne pytania, jednak bez odpowiedzi.

// edit

Pogrzebałem trochę bardziej na forum i coś znalazłem (ręcznie, wyszukiwarka chyba mnie nie lubi), wygląda to nawet zachęcająco:

function StrToPAnsiChar(dane:string):PAnsiChar;
var buf: array[0..1000] of char;
i : integer;
begin
for i:=0 to 1000 do buf[i]:=#0; { musi być zerowanie bufora, patrz info na dole }
for i:=0 to length(dane) do
begin
buf[i]:=dane[i+1];
StrToPAnsiChar:=buf;
end;
end;

Ale mimo wszystko kompilator tego też nie chce łyknąć :/

[DCC Error] Main.pas(125): E2010 Incompatible types: 'Array' and 'PAnsiChar'

Pozdrawiam!

0
  1. Jak skompilujesz projekt w Delphi 7 to też uruchomisz pod systemem 64-bitowym.
  2. Próbowałeś usunąć tą 'kłopotliwą' linijkę??
0
stg napisał(a)
  1. Jak skompilujesz projekt w Delphi 7 to też uruchomisz pod systemem 64-bitowym.
  2. Próbowałeś usunąć tą 'kłopotliwą' linijkę??

Program się nie odpala za 64 bitach i z tego co czytałem z Delphi 7 to nie będzie, a linijki nie mogę usunąć.

0

nie mam d2009 wiec nie sprawdze ale znalazlem cos tkaiego:

function StrToPAnsiChar(s:string):PAnsiChar;
begin
result := PAnsiChar(AnsiString(s));
end;
0
cimak napisał(a)

nie mam d2009 wiec nie sprawdze ale znalazlem cos tkaiego:

function StrToPAnsiChar(s:string):PAnsiChar;
begin
result := PAnsiChar(AnsiString(s));
end;

Kompilator to przepuścił w końcu, ale program się wysypuje na tej linii :/

// edit

Nie sorry nie na tym się wysypuje, ale przez to. Po prostu dane które są odczytywane są niewłaściwe i one powodują błąd programu.
Tak to wygląda:

潣⹭牡晴汵楢獴愮卩獹整坭摩敧⹴灡൫਍潣⹭㉥捥潬摵愮物汰湡浥摯睥摩敧⹴灡൫਍潣⹭汥摳敯晲牥愮摮潲摩愮瑵獯慴瑲⹳灡൫਍潣⹭汳浧扯汩⹥敢浡敲摡牥愮歰഍挊浯琮楮吮獡楋汬牥畆汬愮歰഍

A powinien być zwykły tekst możliwy do przeczytania dla człowieka :/

0
volgar napisał(a)

Program się nie odpala za 64 bitach i z tego co czytałem z Delphi 7 to nie będzie, a linijki nie mogę usunąć.

To dziwne, bo piszę w Delphi 5 i bez problemu odpalam na Windowsie x64. A wracając do problemu, może sprawdź deklarację tej funkcji w nowym Delphi, np. w starej 5'tce wygląda tak:

function OemToAnsi(const lpszSrc: LPCSTR; lpszDst: LPSTR): BOOL

I zobacz jakie konkretnie parametry oraz jaki typ zwraca ta funkcja. Następnie porównaj ze swoją funkcją. Być może wystarczy String(Buffer) lub zmiana typu rezultatu.

0

Użyj PAnsiChar.
W Delphi 2009 i wyżej Char=WideChar, a PChar=PWideChar, a nie jak wcześniej Char=AnsiChar a PChar=PAnsiChar.
W tej chwili funkcja chce PAnsiChar a ty jej dajesz PChar czyli PWideChar.

0
stg napisał(a)

To dziwne, bo piszę w Delphi 5 i bez problemu odpalam na Windowsie x64.

Faktycznie program nie działał na x64 z innego powodu, dałem sobie z tym radę :) . Ale to nie zmienia faktu że nie zamierzam się poddać i odpalę to w D2009, tak dla satysfakcji.

stg napisał(a)

A wracając do problemu, może sprawdź deklarację tej funkcji w nowym Delphi, np. w starej 5'tce wygląda tak:

function OemToAnsi(const lpszSrc: LPCSTR; lpszDst: LPSTR): BOOL

To jest funkcja zawarta w bibliotekach systemowych, nie zależy to od wersji Delphi. Poza tym jest taka sama.

stg napisał(a)

Być może wystarczy String(Buffer) lub zmiana typu rezultatu.

Oczywiście że takie coś testowałem, nie bierz mnie za idiotę. Program się z tym wysypuje.

Azarien napisał(a)

Użyj PAnsiChar.
W Delphi 2009 i wyżej Char=WideChar, a PChar=PWideChar, a nie jak wcześniej Char=AnsiChar a PChar=PAnsiChar.
W tej chwili funkcja chce PAnsiChar a ty jej dajesz PChar czyli PWideChar.

Doskonałe spostrzeżenie, jak dałem PAnsiChar to natychmiast kompilator się odczepił od tej funkcji. Jest jednak teraz problem z tym że moja funkcja ReadResult zwracała PChar (moge zmienić na string najwyżej) i teraz gryzie się z typem buffora. Rzutowanie nie pomaga i nie znam w dalszym ciągu funkcji do konwersji. Jak to zrobić? Skoro to jest też tablica to może po prostu zarzucę pętlę i skopiuję to po kolei do stringa?

// edit

Niestety też nie idzie, nawet jak chcę wartość pojedynczej komórki przydzielić do zmiennej typu PChar (result := buffer[n]) to kompilator tego nie puszcza

0

Nie musisz kopiować znak po znaku, możesz skopiować całego stringa i powinno to go przekonwertować.

1 użytkowników online, w tym zalogowanych: 0, gości: 1