ShadowFlare's Realm
http://sfsrealm.hopto.org/cgi-bin/yabb2/YaBB.pl
ShadowFlare's Realm Forums >> Program Development >> help me SFMQP SFileReadFile with delphi
http://sfsrealm.hopto.org/cgi-bin/yabb2/YaBB.pl?num=1186919513

Message started by hke on Aug 12th, 2007, 11:51am

Title: help me SFMQP SFileReadFile with delphi
Post by hke on Aug 12th, 2007, 11:51am



Code:

function SFileReadFile(hFile: LongWord;
                      lpBuffe:pointer;
                      nNumberOfBytesToRead: LongInt;
                      var lpNumberOfBytesRead: LongInt;
                      lpOverlapped:longword
                      ): Bool;stdcall;external sfmpq;



Code:

var hmpq,hf,filesize:longword;
buff:pointer;
tmp:longint;


     if(SFileOpenFileEx(hmpq,'scripts\war3map.j',0,hf))then
       begin
         filesize:= SFileGetFileSize(hf,0);
         form1.Caption:='Ok'+inttostr(filesize);
         getmem(buff,filesize);
         if SFileReadFile(hf,Buff,filesize,tmp,0) then
           begin
             SaveFile('D:\aa\aa\0\war3map.j',buff,filesize);
             form1.Caption:=inttostr(tmp)+' '+inttostr(filesize);
             Button4.Caption:=string(buff);
           end
         else
           form1.Caption:='Err';
         freemem(buff);



I can find
nNumberOfBytesToRead=lpNumberOfBytesRead
but buff is empty
why?
help me....

Title: Re: help me SFMQP SFileReadFile with delphi
Post by cyronc on Mar 28th, 2008, 3:39pm

disclaimer: i havent worked with SF`s MPQ API right now so i could be TOTALLY OFF!
however i had learned my stuff when trying to implement Windows API into my delphi programms(with documentation suitable for C only), so i know something about the traps a delphi programmer has to be aware when dealing with other source code

first of all the translation of the SFileReadFile function could contain a minor but effective error!!!
most programmers indicate that the type of a variable is in fact a pointer to the standard type by using name-prefix 'lp'(often followed by an '*' before the datatype), so i think it should be lpNumberOfBytesRead: PLongInt or whatever the datatype is

description            delphi type                delphi pointertype
unsigned 1-byte = byte                          pbyte
unsigned 2-bytes=word                                       pword
unsigned 4-bytes=cardinal(or dword)    pcardinal
signed 1-byte =     shortint                                     pshortint(?)
signed 2-byte ---dont remember sorry----
signed 4-bytes=integer(or longint)       pinteger(plongint)

so when implemented you should call SFileReadFile with lpNumberOfBytesRead as an Address/Pointer to your variable!!! you can do this by simply using the '@'-sign before using your variabel called 'tmp'(just type @tmp instead of tmp XOR change tmp to a pointer instead of a number and then use it normally!)

second thing i recognised was, tat you are using a custom SaveFile function.
Important here is which original function it calls, because SOME FUNCTIONS DO ONLY ACCEPT VARIABLES/CONSTANTS as buffer WHILE OTHERS DO SO ONLY FOR POINTERS TO THE DATA!

for example if u use the Delphi-Streams like TFileStream or TMemoryStream they WILL ONLY EVER USE VARIABLES, so you`d have to convert 'buff' to 'buff^' in your custom SaveFile function!! The '^' indicates that not the value OF WHERE the data is(aka address or pointer) is copied BUT the value OF WHAT the data is (aka variable/constant data in memory)


to explain this a bit better:

say you write a program with the variable 'v' and a pointer 'p'

the variable 'v' is automatically assigned its memory inside your runtime process by the program.
for 'p' only the four bytes containing the pointers value are automatically assigned.
now you call getmem(d,somesize) or reallocmem(d,somesize) and your program reserves space with size of somesize in the memory. where that space is is stored as an address in your 4-byte pointer.

that means: if your function needs only some data value it usually wants a variable it can read for
example FunctionName(indata: integer):boolean; would be called FunctionName(v) or FunctionName(p^) accordingly

BUT some functions want access to the actual location where the data is and they usually do this by getting a pointer or address to where the space in memory is!
example OtherFunction(indata: pointer):boolean; would be
called OtherFunction(@v) or OtherFunction(p)

so you have ever to be aware of what your function wants as an argument, a variabel/constant object OR an address/pointer to the object

hope that helps

ShadowFlare's Realm » Powered by YaBB 2.2.1!
YaBB © 2000-2008. All Rights Reserved.