Использование C / C ++ DLL в Delphi 2010 - PullRequest
0 голосов
/ 24 августа 2010

Я хочу использовать dll из ssdeep (http://ssdeep.sourceforge.net/). API:

int fuzzy_hash_buf (без знака char * buf, uint32_t buf_len, char * result);

тогда в Delphi я пишу это так:

function fuzzy_hash_buf (buf: Pbyte; buf_len: Cardinal; результат: PAnsiChar): целое число; STDCALL; внешнее имя 'fuzzy.dll' 'fuzzy_hash_buf';

Как использовать эту функцию в Delphi?

Спасибо!

Ответы [ 2 ]

1 голос
/ 24 августа 2010

Помимо возможного неправильного соглашения о вызовах (stdcall или cdecl), похоже, что вы правильно объявили эту функцию.

Исходя из имен и типов параметров, моя догадка заключается в том, что вы должны передать указатель на массив байтов в первом параметре, а во втором параметре вы сообщаете функции, сколько байтов вы ей дали.Вы также передаете указатель на массив символов, который функция заполнит для вас.Размер этого массива равен , предполагается, что достаточно большой, чтобы вместить все, что будет помещена функцией.Результатом функции, вероятно, является код состояния, указывающий на успех или неудачу.

Консультации Документация показывает, что мои догадки верны.Буфер результата должен быть длиной не менее FUZZY_MAX_RESULT байтов.Вы можете получить это, объявив массив символов:

var
  HashResult: array[0..Fuzzy_Max_Result] of AnsiChar;

Передайте это функции:

status := fuzzy_hash_buf(buffer, buffer_length, HashResult);
if status <> 0 then
  Abort;
HashResult[Fuzzy_Max_Result] := #0;
ShowMessage(HashResult);

В документации ничего не сказано о том, что результирующий буфер равен нулю, поэтому мы резервируем дополнительный байт в конце, а затем помещаем туда нулевой символ.Это позволяет безопасно передавать буфер результатов в функции типа ShowMessage, которые ожидают string параметров.

1 голос
/ 24 августа 2010

Если fuzzy.dll экспортирует функцию fuzzy_hash_buf с объявлением C

int fuzzy_hash_buf(unsigned char *buf, uint32_t buf_len, char *result);

тогда вы правы, что объявление Delphi будет

function fuzzy_hash_buf(buf: PAnsiChar; buf_len: cardinal; result: PAnsiChar):
  integer;

Чтобы использовать это в Delphi, в секции interface единицы напишите

function fuzzy_hash_buf(buf: PAnsiChar; buf_len: cardinal; result: PAnsiChar):
  integer; stdcall;

Затем в разделе implementation того же самого модуля вы сами не реализуете функцию, а указываете на внешнюю DLL:

function fuzzy_hash_buf; external 'fuzzy.dll' name 'fuzzy_hash_buf`

Обратите внимание, что вам не нужно повторно объявлять параметры, тип результата и соглашение о вызовах (stdcall).

Теперь вы можете использовать эту функцию, как если бы она была реальной функцией данного устройства. Например, вы можете написать

val := fuzzy_hash_buf(buf, len, output);

от любого устройства, uses от которого вы объявили fuzzy_hash_buf.

Обновление

Боюсь, что я недостаточно знаком с функцией CreateFileMapping . Тем не менее, после прочтения документации MSDN, я считаю, что вы можете сделать

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.
...