Utilisation de DLL C / C ++ dans Delphi 2010

Je veux utiliser dll de ssdeep ( http://ssdeep.sourceforge.net/ ). L’API est:

int fuzzy_hash_buf (char non signé * buf, uint32_t buf_len, char * résultat);

puis à Delphi, je l’écris comme ceci:

fonction fuzzy_hash_buf (buf: Pbyte; buf_len: Cardinal; résultat: PAnsiChar): entier; stdcall; nom ‘fuzzy.dll’ externe ‘fuzzy_hash_buf’;

Comment utiliser cette fonction dans Delphi?

Merci!

Si fuzzy.dll exporte une fonction fuzzy_hash_buf avec la déclaration C

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

alors vous avez raison de dire que la déclaration Delphi serait

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

Pour utiliser ceci dans Delphi, dans la section interface d’une unité, écrivez

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

Ensuite, dans la section implementation de la même unité, vous n’implémentez pas la fonction vous-même, mais vous pointez plutôt sur la DLL externe:

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

Notez qu’il n’est pas nécessaire de redéclarer les parameters, le type de résultat et la convention d’appel ( stdcall ).

Vous pouvez maintenant utiliser cette fonction comme s’il s’agissait d’une fonction réelle de cet appareil. Par exemple, vous pourriez écrire

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

de toute unité qui uses l’unité dans laquelle vous avez déclaré fuzzy_hash_buf .

Mettre à jour

Je crains de ne pas être suffisamment familiarisé avec la fonction CreateFileMapping . Cependant, après avoir lu la documentation MSDN, je pense que vous pouvez faire

 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. 

En plus d’avoir éventuellement une convention d’appel erronée ( stdcall ou cdecl ), il semble que vous ayez déclaré cette fonction correctement.

En fonction des noms et des types de parameters, je suppose que vous êtes censé passer un pointeur sur un tableau d’octets dans le premier paramètre et dans le second paramètre, vous indiquez à la fonction le nombre d’octets que vous lui avez atsortingbués. Vous passez également un pointeur sur un tableau de caractères que la fonction remplira pour vous. La taille de ce tableau est supposée être assez grande pour contenir quelle que soit la fonction qui y sera placée. Le résultat de la fonction est probablement un code d’état indiquant le succès ou l’échec.

Consulter la documentation montre que mes suppositions sont correctes. Le tampon de résultat doit comporter au moins FUZZY_MAX_RESULT octets de long. Vous pouvez obtenir cela en déclarant un tableau de caractères:

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

Passez cela à la fonction:

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

La documentation ne dit rien sur le fait de s’assurer que le tampon de résultat est terminé par un octet nul. Nous réservons donc un octet supplémentaire à la fin, puis nous y plaçons un caractère nul. Cela permet en toute sécurité de transmettre le tampon de résultat à des fonctions telles que ShowMessage qui attendent ssortingng parameters de ssortingng .