I want to use dll from ssdeep ( http://ssdeep.sourceforge.net/ ). The API is:
int fuzzy_hash_buf(unsigned char *buf, uint32_t buf_len, char *result);
then in Delphi, i write it like this:
function fuzzy_hash_buf(buf : Pbyte; buf_len : Cardinal; result : PAnsiChar): integer; stdcall; external 'fuzzy.dll' name 'fuzzy_hash_buf';
How to use that function in Delphi?
Thanks!
If fuzzy.dll
exports a function fuzzy_hash_buf
with the C declaration
int fuzzy_hash_buf(unsigned char *buf, uint32_t buf_len, char *result);
then you are right that the Delphi declaration would be
function fuzzy_hash_buf(buf: PAnsiChar; buf_len: cardinal; result: PAnsiChar):
integer;
To use this in Delphi, in the interface
section of a unit, write
function fuzzy_hash_buf(buf: PAnsiChar; buf_len: cardinal; result: PAnsiChar):
integer; stdcall;
Then, in the implementation
section of the very same unit, you do not implement the function yourself, but rather point to the external DLL:
function fuzzy_hash_buf; external 'fuzzy.dll' name 'fuzzy_hash_buf`
Notice that you do not have to redeclare the parameters, the result type, and the calling convention ( stdcall
).
Now you can use this function as if it were an actual function of this unit. For instance, you might write
val := fuzzy_hash_buf(buf, len, output);
from any unit that uses
the unit in which you declared fuzzy_hash_buf
.
I am afraid that I am not familiar enough with the CreateFileMapping function. However, after reading the MSDN documentation, I believe that you can do
var
buf: PAnsiChar;
buf := MapViewOfFile(FFileMappingHandle, FILE_MAP_READ, 0, 0, 0);
// Now, if I have understood MapViewOfFile correctly, buf points to the first byte of the file.
var
StatusCode: integer;
TheResult: PAnsiChar;
GetMem(TheResult, FUZZY_MAX_RESULT);
StatusCode := fuzzy_has_buf(buf, FFileSize, TheResult);
// Now TheResult points to the first byte (character) of the output of the function.
Aside from possibly having the calling convention wrong ( stdcall
or cdecl
), it looks like you have declared that function correctly.
Based on the parameter names and types, my guess is that you're supposed to pass a pointer to an array of bytes in the first parameter, and in the second parameter you tell the function how many bytes you've given it. You also pass a pointer to an array of characters that the function will fill for you. The size of that array is assumed to be large enough to hold whatever the function will put there. The function result is probably a status code indicating success or failure.
Consulting the documentation shows that my guesses are correct. The result buffer should be at least FUZZY_MAX_RESULT
bytes long. You could get that by declaring an array of characters:
var
HashResult: array[0..Fuzzy_Max_Result] of AnsiChar;
Pass that to the function:
status := fuzzy_hash_buf(buffer, buffer_length, HashResult);
if status <> 0 then
Abort;
HashResult[Fuzzy_Max_Result] := #0;
ShowMessage(HashResult);
The documentation doesn't say anything about ensuring that the result buffer is null-terminated, so we reserve an extra byte on the end, and then put a null character there. That makes it safe to pass the result buffer to functions like ShowMessage
that expect string
parameters.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.