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

发布于 2024-09-15 18:27:04 字数 412 浏览 5 评论 0原文

我想使用 ssdeep 的 dll (http://ssdeep.sourceforge.net/)。 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;标准调用;外部“fuzzy.dll”名称“fuzzy_hash_buf”;

在Delphi中如何使用该函数?

谢谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅暮の光 2024-09-22 18:27:04

如果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;

To use this in Delphi, in the 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);

使用在其中声明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.

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.
无边思念无边月 2024-09-22 18:27:04

除了调用约定可能错误(stdcallcdecl)之外,看起来您已经正确声明了该函数。

根据参数名称和类型,我的猜测是您应该在第一个参数中传递一个指向字节数组的指针,并在第二个参数中告诉函数您有多少字节已经给了。您还可以传递一个指向该函数将为您填充的字符数组的指针。该数组的大小假设足以容纳函数将放在那里的任何内容。函数结果可能是指示成功或失败的状态代码。

查阅文档表明我的猜测是正确的。结果缓冲区的长度应至少为 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 终止,因此我们在末尾保留一个额外的字节,然后放置一个 null那里的人物。这使得可以安全地将结果缓冲区传递给像 ShowMessage 这样需要 string 参数的函数。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文