Проблема с извлечением ресурса

  • Автор темы Dzmitry Kalesnikau
  • Дата начала
Статус
Закрыто для дальнейших ответов.
D

Dzmitry Kalesnikau

Гость
#1
Уважаемые программисты.
Есть следующий код:
Код:
program ExtrResSave;

function LoadResource(hModule: CARDINAL; hResInfo: CARDINAL):CARDINAL; stdcall; external 'kernel32.dll' name 'LoadResource';
function FindResource(hModule: CARDINAL; lpName, lpType: PChar): CARDINAL; stdcall; external 'kernel32.dll' name 'FindResourceA';
function LockResource(hResData: CARDINAL): Pointer; stdcall; external 'kernel32.dll' name 'LockResource';
function LoadLibrary(lpLibFileName: PChar): CARDINAL; stdcall; external 'kernel32.dll' name 'LoadLibraryA';
function FreeLibrary(hLibModule: CARDINAL): BOOLEAN; stdcall; external 'kernel32.dll' name 'FreeLibrary';
function GetCommandLine: PChar; stdcall; external 'kernel32.dll' name 'GetCommandLineA';

var pData: Pointer; libr:CARDINAL; f:textfile; s:string;

begin
libr:=LoadLibrary(GetCommandLine);
pData:=LockResource(LoadResource(libr, FindResource(libr,'EXEDATA',PChar(10))));
AssignFile(f,'tmp.dat');
Rewrite(f);
s:=PChar(pData);
Write(f,s);
Closefile(f);
FreeLibrary(libr);
end.
Код в принципе рабочий, но почему-то в файл извлекается не весь ресурс, а его определённый кусок. Извлечение прекращается, как только в коде ресурса встречается байт $00. Тоесть извлекается кусок ресурса только до позиции первого же $00 в нём и всё. При этом никаких ошибок не возникает.
В связи с этим и вопросы: Почему так происходит? Как устранить проблему? Какой есть рабочий код для этого?
 
B

Barmutik

Гость
#2
Ну однозначно почему ..#0 - это признать конца PChar... вот только до него и читает ...

А не проще ли воспользовать готовым классом TResourceStream и потом прямо из него сохранить в нужный Вам файл?
 
D

Dzmitry Kalesnikau

Гость
#3
Спасибо, понял теперь почему. Но готовым классом пользоваться нельзя, т.к. в данном случае требуется минимальный размер скомпилированного приложения. Возможно даже придётся самостоятельно осуществлять запись в файл и работу со строками, дабы отказаться от sysinit.pas и system.pas. А так конечно, с TResourceStream работать легко и я уже делал, а тут на чистом API нужно. Но тогда как правильно читать ресурс, если $00 останавливает считывание?
И интересно то, что если брать pData из ресурса (например звукового файла wav) и подавать его функции PlaySound(PChar(pData),0,$04) так, то несмотря на содержание в коде ресурса неоднократно $00 считывание ресурса происходит до конца - звуковой файл полностью проигрывается. Но при попытке парралельно проигрыванию сохранить этот ресурс в файл он, как обычно, только до первого $00.
Как можно сохранить pData в файл? Я так понимаю, что данные в pData - просто последовательность байт, может попробовать сохранять в нетипизированный файл побайтно, вот как только...
 
B

Barmutik

Гость
#4
Вы не путайте одно с другим .. когда Вы преобразуете в строку s:=PChar(pData); Вы теряете всё что хранится после #0.

А что Вам мешает напрямую записать в файл блок памяти? Зачем пробразовывать в строку?
 
D

Dzmitry Kalesnikau

Гость
#5
Дело в том, что там планируется ещё добавить обработку строки s одной функцией (я буду заменять некоторые символы на другие в этой строке), перед тем как записать в файл.
 
B

Barmutik

Гость
#6
Так а кто мешает заменять напрямую в блоке памяти ? Зачем преобразоваине в строку?

Этим преобразованием Вы существенно снижаете возможности Вашей программы.. не говоря уже о дополнительных глюках со специальными символами...
 
Статус
Закрыто для дальнейших ответов.