2010-08-24 4 views
0

Je souhaite utiliser dll à partir de ssdeep (http://ssdeep.sourceforge.net/). L'API est:Utilisation de la DLL C/C++ dans Delphi 2010

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

puis en Delphi, j'écrire comme ceci:

fonction fuzzy_hash_buf (buf: PByte; buf_len: Cardinal; résultat: PAnsiChar): nombre entier; stdcall; nom 'fuzzy.dll' externe 'fuzzy_hash_buf';

Comment utiliser cette fonction dans Delphi?

Merci!

Répondre

1

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 que la déclaration Delphi serait

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

Pour utiliser dans Delphi, dans la section interface d'un unité, écrire

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

n, dans la partie implementation de la même unité, vous ne met pas en œuvre la fonction vous, mais pointent plutôt à la DLL externe:

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

Notez que vous n'avez pas redéclarer les paramètres, 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 pouvez écrire

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

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

Mise à jour

Je crains que je ne suis pas assez familier avec la fonction CreateFileMapping. Cependant, après avoir lu la documentation MSDN, je crois 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. 
+0

Merci Andreas, je le sais. J'ai tampon à partir du fichier (lire en utilisant CreateFile, CreateFileMapping), comment passer ce tampon au premier paramètre? Merci! – MrKimbo

+0

Non, je sais comment utiliser CreateFileMapping, le problème n'est pas cela. Je veux dire comment passer le tampon de fichier à fuzzy_hash_buf (buffer ..). Je l'ai essayé. Voir mon code: GetMem (Ssdeep, FUZZY_MAX_RESULT); GetMem (Ssdeep_Buf, FFileSize); Ssdeep_Buf: = @PAnsiChar (FFileMappingPtr) [0]; Hash.Ssdeep: = AnsiString (fuzzy_hash_buf (Ssdeep_Buf, FFileSize, Ssdeep)); Résultat: Erreur de violation d'accès. Je ne sais pas où est le problème. – MrKimbo

+0

Qu'est-ce que 'FFileMappingPtr'? Si c'est le 'buf' de mon code ci-dessus, alors utilisez simplement ceci comme premier argument de' fuzzy_hash_buf'. Alors 'FFileMappingPtr' est un pointeur (* le *), vous n'avez donc pas besoin de prendre l'adresse de ceci (en utilisant' @ '). En outre, la partie '[0]' semble très étrange. Enfin, 'fuzzy_hash_buf' renvoie un code d'état, pas une chaîne. La chaîne est écrite dans le tampon du dernier paramètre! –

1

Mis à part peut-être avoir la mauvaise convention d'appel (stdcall ou cdecl), il semble que vous avez déclaré à juste titre que la fonction. Sur la base des noms et des types de paramètres, mon devine est 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 combien d'octets vous ' Je l'ai donné. Vous passez également un pointeur vers un tableau de caractères que la fonction remplira pour vous. La taille de ce tableau est supposé être assez grand pour contenir tout ce que la fonction mettra là. Le résultat de la fonction est probablement un code d'état indiquant le succès ou l'échec.

Consultation the documentation montre que mes estimations sont correctes. Le tampon de résultat doit avoir au moins FUZZY_MAX_RESULT octets.Vous pouvez obtenir ce en déclarant un tableau de caractères:

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

passe que 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 à faire en sorte que le tampon de résultat est nul terminé, donc nous réservons un octet supplémentaire à la fin, et y mettons un caractère nul. Cela rend sûr de passer le tampon de résultat à des fonctions comme ShowMessage qui attendent string paramètres.

+0

Salut Rob, Merci pour la réponse! Oui, vous êtes vrai, mais je ne sais toujours pas comment passer le premier paramètre. Le tampon provient d'un tampon de fichier, comme ceci: FFileHandle: = CreateFile (PWideChar (WideString (FFileName)), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); si FFileHandle <> INVALID_HANDLE_VALUE puis FFileMappingHandle: = CreateFileMapping (FFileHandle, nil, PAGE_READONLY, 0, FFileSize, nil); Maintenant, j'ai le tampon de fichier, mais comment passer au premier paramètre (tampon)? Merci! – MrKimbo

+0

Vous n'avez * pas encore le tampon. Vous avez un handle de mappage de fichier. Pour obtenir une adresse tampon, vous devez appeler 'MapViewOfFile'. Mais si vous voulez hacher le fichier entier, utilisez la fonction de hachage de fichier au lieu de la fonction de hachage de la mémoire: 'fuzzy_hash_filename'. –

+0

Oui, j'ai MapViewOfFile. Le fuzzy_hash_filename est exécuté correctement, mais dans ce cas, je veux utiliser fuzzy_hash_buf, donc je peux déterminer la taille de la mémoire tampon (pas le fichier entier). – MrKimbo

Questions connexes