Перевести код с C на Delphi, Программирование
|
Soloton
Грамотный
Группа: Наши Люди Сообщений: 292 Регистрация: 18.12.2005 Из: Невинномысск Пользователь №: 88.260
Респектов: 72
| Есть код на C++: » Нажмите, для открытия спойлера | Press to open the spoiler « Code wchar_t *ReadString (FILE *file, wchar_t *Dest, int nDestLength, int nCodePage) { char *lpDest = (char*)xf_malloc ((nDestLength+1)*3); //UTF-8, up to 3 bytes per char support
memset (lpDest, 0, (nDestLength+1)); memset (Dest, 0, nDestLength*sizeof (wchar_t));
if ( nCodePage != -1 ) { if ( fgets (lpDest, nDestLength, file) ) MultiByteToWideChar (nCodePage, 0, lpDest, -1, Dest, nDestLength); else { free (lpDest); return NULL; } }
free (lpDest);
return lpwszDest; } Нужно сделать аналог функции на Delphi. Особенностью задачи является использование API и обязательный отказ от громоздких модулей типа SysUtils, в идеале нужно вообще оставить в uses только Windows. Прошу помощи. | |
| |
26.08.2009 - 16:52 |
yah
профи!
[SoftoRooMTeaM]
Группа: Наши Люди Сообщений: 2.336 Регистрация: 27.01.2006 Из: рнд Пользователь №: 500
Респектов: 408
| Если ты хочешь использовать API-функции, то никаких проблем, связанных с языком C++\Delphi, возникнуть не должно, т.к. API - он и в африке API. Если брать СИ-шные функии, то для них есть аналоги в Делфи: 1. "xf_malloc" - не встречался. Встречалась только функция malloc (если язык - С++, то куда уместнее было бы использовать new\delete для работы с памятью). Для Си-шного "malloc" есть делфи-аналоги GetMem/FreeMem, New/Dispose, либо SetLength/Finalize. 2. "memset" - можно использовать ZeroMemory. 3. Для работы с указателями вместо СИ-шных *\& используется делфи-аналоги ^\@. | |
| |
27.08.2009 - 7:19 |
Soloton
Грамотный
Группа: Наши Люди Сообщений: 292 Регистрация: 18.12.2005 Из: Невинномысск Пользователь №: 88.260
Респектов: 72
| Цитата | Quote(yah @ 26.08.2009 - 16:52) "xf_malloc" - не встречался. Это оболочка для malloc, используется по всему коду, который перевожу, можно префикс xf_ опустить, смысл от этого не поменяется. Собственно проблемы с fgets (). Что из Delphi-функций может быть использовано вместо неё? Пробовал так: » Нажмите, для открытия спойлера | Press to open the spoiler « Code function ReadString (Afile: hFile; Dest: PChar; nDestLength, nCodePage: DWORD): PChar; var lpDest: PAnsiChar; nLength: integer; nNewLength: integer; begin GetMem(lpDest, (nDestLength+1)); FillMemory(lpDest, (nDestLength+1), 0); ReadFile(Afile, lpDest^, nDestLength, nDestLength, nil); if nDestLength <> 0 then begin MultiByteToWideChar(CP_OEMCP, 0, lpDest, nDestLength, Dest, nDestLength); end else begin FreeMem(lpDest); exit; end; FreeMem(lpDest); // <-- Тут AV GetMem(Result, nDestLength+1); lstrcpy(Result, Dest); lstrcat(Result, #0); end; Получаю AV при попытке освобождения памяти. Если не использовать ReadFile, то всё нормально, правда тогда ф-я вообще ничего не читает. | |
| |
27.08.2009 - 10:06 |
yah
профи!
[SoftoRooMTeaM]
Группа: Наши Люди Сообщений: 2.336 Регистрация: 27.01.2006 Из: рнд Пользователь №: 500
Респектов: 408
| Цитата | Quote function ReadString (Afile: hFile; Dest: PChar; nDestLength, nCodePage: DWORD): PChar; var lpDest: PAnsiChar; nLength: integer; nNewLength: integer; begin GetMem(lpDest, (nDestLength+1)); FillMemory(lpDest, (nDestLength+1), 0); ReadFile(Afile, lpDest^, nDestLength, nDestLength, nil); if nDestLength <> 0 then begin MultiByteToWideChar(CP_OEMCP, 0, lpDest, nDestLength, Dest, nDestLength); end else begin FreeMem(lpDest); - освободили память.... exit; end; FreeMem(lpDest); // <-- "Тут AV". Пытаемся освободить память, которую освободили ранее. Получаем AV. GetMem(Result, nDestLength+1); lstrcpy(Result, Dest); lstrcat(Result, #0); end;
| |
| |
27.08.2009 - 10:48 |
stepanyk
Грамотный
Группа: Пользователи Сообщений: 232 Регистрация: 5.10.2006 Пользователь №: 241.996
Респектов: 55
Предупреждений: 0
| yah, это тут не при чем: » Нажмите, для открытия спойлера | Press to open the spoiler « Code function ReadString (Afile: hFile; Dest: PChar; nDestLength, nCodePage: DWORD): PChar; var lpDest: PAnsiChar; nLength: integer; nNewLength: integer; begin GetMem(lpDest, (nDestLength+1)); FillMemory(lpDest, (nDestLength+1), 0); ReadFile(Afile, lpDest^, nDestLength, nDestLength, nil); if nDestLength <> 0 then begin MultiByteToWideChar(CP_OEMCP, 0, lpDest, nDestLength, Dest, nDestLength); end else begin FreeMem(lpDest); //<- освободили память.... exit;//<-- прерывает функцию end; FreeMem(lpDest); // <-- "Тут AV". Сюда не доходит GetMem(Result, nDestLength+1); lstrcpy(Result, Dest); lstrcat(Result, #0); end;
а может попробовать CloseHandle сделать? Вдруг поможет: » Нажмите, для открытия спойлера | Press to open the spoiler « Code var hFile: Cardinal; ... hFile:=ReadFile(Afile, lpDest^, nDestLength, nDestLength, nil); ... CloseHandle(hFile);
| |
| |
27.08.2009 - 11:03 |
Soloton
Грамотный
Группа: Наши Люди Сообщений: 292 Регистрация: 18.12.2005 Из: Невинномысск Пользователь №: 88.260
Респектов: 72
| Цитата | Quote(stepanyk @ 27.08.2009 - 10:48) а может попробовать CloseHandle сделать? BOOL WINAPI ReadFile( __in HANDLE hFile, __out LPVOID lpBuffer, __in DWORD nNumberOfBytesToRead, __out_opt LPDWORD lpNumberOfBytesRead, __inout_opt LPOVERLAPPED lpOverlapped ); Как интересно ваш код сработает, если API-функция ReadFile возвращает совсем не хэндл файла? Я его в парамертрах к своей функции пишу, и закрываю вне функции. | |
| |
27.08.2009 - 11:05 |
yah
профи!
[SoftoRooMTeaM]
Группа: Наши Люди Сообщений: 2.336 Регистрация: 27.01.2006 Из: рнд Пользователь №: 500
Респектов: 408
| Цитата | Quote(stepanyk @ 27.08.2009 - 11:48) Тогда следует проверить функцию GetMem(lpDest, (nDestLength+1)). Может, по неизвестной причине, не происходит выделения памяти. Советы: 1. Смотреть в отладчике шаг GetMem(lpDest, (nDestLength+1)); 2. Посмотреть адрес, на который указывает указатель lpDest после вызова MultiByteToWideChar(CP_OEMCP, 0, lpDest, nDestLength, Dest, nDestLength); 3. Посмотреть адрес, на который указывает указатель lpDest до и после первого вызова FreeMem(lpDest); 4. Посмотреть адрес, на который указывает указатель lpDest до и после второго вызова FreeMem(lpDest); 5. "а может попробовать CloseHandle сделать? Вдруг поможет:"(с) | |
| |
|
|