Forum > General
[SOLVED] Passing static array of byte by reference... without creating copies
BigChimp:
I've read
http://stackoverflow.com/questions/3911432/pass-static-byte-array-in-parameter-in-delphi
and tried to apply it.... without success... or perhaps with other complications.
More eyes welcome
The program recurses through files/directories, and stores details in a Firebird (embedded0 database. Sort of like locate
My goal: have 1 buffer that is used for all md5 calculations instead of having duplicates.
The application is single threaded so 1 buffer should be ok..
In search.pas, the search happens in AddFileToResult
FFileBuffer should create a new array once...
--- Code: --- TFileSearch = class
private
...
// Buffer that can be used by e.g. md5 hashes
FFileBuffer: TFileBuffer; //Buffer used e.g. in md5 calculations, defined in flocatecommon as array[1...1024*1024] of byte
--- End code ---
...and this is passed to the directoryentry constructor (should be as reference)...
--- Code: ---procedure TFileSearch.AddFileToResult(const ThisDir: String; item: TSearchRec);
// Finds out properties of file specified in item, adds this information
// to a record, and adds a pointer in the Res list to this record.
var
DirEntry: TDirectoryEntry;
begin
assert(ThisDir <> '', 'Directory to be searched may not be empty');
assert(Item.Name <> '', 'File to be searched must have a filename');
//Create a new file object and let it figure out all properties of the file.
DirEntry := TDirectoryEntry.Create(ThisDir + Item.Name,FFileBuffer,FReadFileContents);
--- End code ---
... then directoryentry.pas does this
--- Code: --- TDirectoryEntry = class(TObject)
private
...
FFileBuffer: TFileBuffer; //buffer for e.g. md5 etc can be reused.
--- End code ---
... this worries me, AFAIU, this will generate a new array. How can I declare the right variable here?
The constructor then goes on
--- Code: ---constructor TDirectoryEntry.Create(FullPath: string; var FileBuffer: TFileBuffer; ReadFileContents: boolean);
begin
...
FFileBuffer:=FileBuffer;
--- End code ---
Attached complete code for Win/Linux; it creates a firebird embedded db if it doesn't exist (requires fb dll/lib of course)
Thanks!
User137:
The format on dynamic and static array are little different, so it's not directly possible i'd assume, without hacks. Easy solution would be to use array pointer
--- Code: ---type
PFileBuffer = ^TFileBuffer;
...
private
...
FFileBuffer: PFileBuffer;
--- End code ---
Leledumbo:
Do as User137 suggests. Even if the parameter is declared by reference, assignment between static arrays does a deep copy. Well actually, even if you don't assign anything to TDirectoryEntry.FFileBuffer, when you create TDirectoryEntry instance, each will already occupy the its own 1 MB space. Assignment only copies the values.
BigChimp:
Thanks a lot, that does seem to work fine!
User137:
Another solution came to mind, that FileBuffer would be a array property, which uses getter function directly to original static array. It has benefit of having simpler syntax when coding with, no pointer confusions with ^ symbols.
Navigation
[0] Message Index
[#] Next page