简体   繁体   中英

Using C/C++ DLL in Delphi 2010

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 .

Update

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM