我想使用ssdeep(http://ssdeep.sourceforge.net/)中的dll。 API是:
int fuzzy_hash_buf(unsigned char * buf,uint32_t buf_len,char * result);
然后在Delphi中,我这样写:
function fuzzy_hash_buf(buf:Pbyte; buf_len:Cardinal; result:PAnsiChar):integer; STDCALL;外部'fuzzy.dll'名称'fuzzy_hash_buf';
如何在Delphi中使用该功能?
谢谢!
答案 0 :(得分:1)
如果fuzzy.dll
使用C声明导出函数fuzzy_hash_buf
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.
答案 1 :(得分:1)
除了可能使调用约定错误(stdcall
或cdecl
)之外,看起来您已正确声明该函数。
根据参数名称和类型,我的 guess 是你应该在第一个参数中传递一个指向字节数组的指针,在第二个参数中你告诉函数如何你给它的很多字节。您还可以将指针传递给函数将为您填充的字符数组。该数组的大小假设足够大以容纳函数放在那里的任何东西。函数结果可能是指示成功或失败的状态代码。
咨询the documentation表明我的猜测是正确的。结果缓冲区的长度至少应为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);
文档没有说明确保结果缓冲区是以null结尾的,所以我们在末尾保留一个额外的字节,然后在那里放一个空字符。这样可以安全地将结果缓冲区传递给期望ShowMessage
参数的string
等函数。