Welcome, Guest. Please Login
Back to main page
  News:
Welcome to the ShadowFlare's Realm Forums.  New registrations are by request only.  To be considered for a new forum account, send an e-mail with the user name and display name you want and the reason you want to register.
  Home SFRealm HelpSearchLogin  
 
Pages: 1
Send Topic Print
help me SFMQP SFileReadFile with delphi (Read 4537 times)
hke
Peon
*
Offline

I love YaBB 1G -
SP1!

Posts: 1

help me SFMQP SFileReadFile with delphi
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....
Back to top
 
 
  IP Logged
cyronc
Peon
*
Offline

iH82G8!

Posts: 1

Re: help me SFMQP SFileReadFile with delphi
Reply #1 - 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
Back to top
 
 
  IP Logged
Pages: 1
Send Topic Print