简体   繁体   English

在Delphi 2010中使用C / C ++ DLL

[英]Using C/C++ DLL in Delphi 2010

I want to use dll from ssdeep ( http://ssdeep.sourceforge.net/ ). 我想使用ssdeep( http://ssdeep.sourceforge.net/ )中的dll。 The API is: 该API是:

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

then in Delphi, i write it like this: 然后在Delphi中,我这样写:

function fuzzy_hash_buf(buf : Pbyte; buf_len : Cardinal; result : PAnsiChar): integer; 函数Fuzzy_hash_buf(buf:Pbyte; buf_len:Cardinal;结果:PAnsiChar):整数; stdcall; STDCALL; external 'fuzzy.dll' name 'fuzzy_hash_buf'; 外部'fuzzy.dll'名称'fuzzy_hash_buf';

How to use that function in Delphi? 如何在Delphi中使用该功能?

Thanks! 谢谢!

If fuzzy.dll exports a function fuzzy_hash_buf with the C declaration 如果fuzzy.dll使用C声明导出函数fuzzy_hash_buf

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

then you are right that the Delphi declaration would be 那么您是对的,Delphi声明将是

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 要在Delphi中使用它,在单元的interface部分中,编写

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: 然后,在同一单元的implementation部分中,您无需自己实现功能,而是指向外部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 ). 请注意,您不必重新声明参数,结果类型和调用约定( 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 . uses声明了fuzzy_hash_buf的单位的任何单位中fuzzy_hash_buf

Update 更新

I am afraid that I am not familiar enough with the CreateFileMapping function. 恐怕我对CreateFileMapping函数还不够熟悉。 However, after reading the MSDN documentation, I believe that you can do 但是,阅读完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.

Aside from possibly having the calling convention wrong ( stdcall or cdecl ), it looks like you have declared that function correctly. 除了可能使调用约定错误( stdcallcdecl )之外,看起来您已经正确声明了该函数。

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. 结果缓冲区的长度至少应为FUZZY_MAX_RESULT个字节。 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. 文档中没有任何关于确保结果缓冲区以null终止的说明,因此我们在末尾保留了一个额外的字节,然后在其中放置了null字符。 That makes it safe to pass the result buffer to functions like ShowMessage that expect string parameters. 这样可以安全地将结果缓冲区传递给需要string参数的ShowMessage函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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