Après windows pour les nuls, voici PB pour les bons (ou presque).

Le forum (ô combien francophone) des utilisateurs de Powerbuilder.

Recherche rapide

Annonce

Certaines rubriques, dont des cours, sont uniquement visibles par les membres du forum ^^.
Dans la rubrique Liens & Références, vous avez accès à un sommaire de téléchargement, profitez-en !
Il existe maintenant un nouveau TOPIC "Votre CV en Ligne" accessible uniquement par demande.
  • Index
  •  » Powerscripts
  •  » Correspondance de type char** entre DLL C++ et PowerBuilder

#1 01-10-2008 07:51:41

Nyphel  
Membre Power Geek
Lieu: Grenoble
Date d'inscription: 06-05-2008
Messages: 253
Pépites: 12
Banque: 529,705,333,097,693

Correspondance de type char** entre DLL C++ et PowerBuilder

Bonjour,

Je fais appel à un objet COM.
Tous mes appels de méthodes fonctionnent correctement sauf un, et je ne parviens pas à trouver la solution.

Voici l'en-tête de la méthode de l'objet :

Code: cpp

void GetDecryptedFile(unsigned char** ppbFileContents);

Voici mon appel depuis PowerBuilder :

Code: pb

string ls_content
ioo_my_ole_object.GetDecryptedFile(ref ls_content)

Et là ça crash avec une erreur R0035 : "Error: Error calling external function GetDecryptedFile at line ... in ... event of object ..."
Je pense donc qu'il s'agit d'un problème de paramètre, et je ne vois pas la solution. Je dispose de la longueur de la chaine de caractère qui doit être assignée par GetDecryptedFile(), peut-être que ça peut aider ?

Je vous remercie, encore une fois, pour votre aide !

Dernière modification par Nyphel (01-10-2008 07:52:11)

Hors ligne

 

#2 01-10-2008 08:27:58

Cortex  
Modérateur
Lieu: Arlon
Date d'inscription: 08-02-2008
Messages: 194
Pépites: 6,904
Banque: 2,109,818,425,070

Re: Correspondance de type char** entre DLL C++ et PowerBuilder

Nyphel a écrit:

Je dispose de la longueur de la chaine de caractère qui doit être assignée par GetDecryptedFile(), peut-être que ça peut aider ?

Peut-être... L'idéal serait de jeter un oeil sur la doc de l'API dont ce GetDecryptedFile fait partie...
En attendant, je vois 2 choses à tester:
1 - comme tu connais la longueur de la chaine qui doit etre assignée, initialise ta variable string avec

Code: pb

string ls_content
ls_content = space(x) // avec x la longeur à utiliser
ioo_my_ole_object.GetDecryptedFile(ls_content) // Ne met pas de 'ref' lors de l'appel, j'ose espérer que
// c'était une faute de frappe de ta part ;)

Souvent, ce genre d'API bas niveau ne prennent pas le temps d'initialiser l'espace mémoire des variables qu'ils sont sensé utiliser, partant du principe que cela doit déjà avoir été fait.

2 - Comme on a affaire à un pointeur de pointeur, ça me fait penser à un souci que j'ai trop souvent rencontré. Essaye ce qui suit:

Code: pb

string ls_content
long ll_content
ioo_my_ole_object.GetDecryptedFile(ll_content)
if ll_content > 0 then
   ls_content = string(ll_content, 'address')
end if

Hors ligne

 

#3 01-10-2008 08:34:37

Nyphel  
Membre Power Geek
Lieu: Grenoble
Date d'inscription: 06-05-2008
Messages: 253
Pépites: 12
Banque: 529,705,333,097,693

Re: Correspondance de type char** entre DLL C++ et PowerBuilder

Bonjour Cortex, et merci pour ta réponse !

A vrai dire le 'ref' était intentionnel, puisque je pensais devoir passer un pointeur sur ma variable... Mais je sens que j'ai mal compris les choses .
Par contre je ne dispose pas vraiment de documentation en ce qui concerne la méthode, j'en ai demandé tout à l'heure mais bon... Je ne suis pas certain d'obtenir quoi que ce soit de concluent.

J'ai testé les deux solutions proposées, et toutes deux me retournent le même message d'erreur que précédemment ("Error: Error calling external function GetDecryptedFile at line ... in ... event of object ..."). Autant je comprends bien l'idée de la première solution, autant j'ai du mal à saisir la seconde. La méthode me retournerait en fait l'adresse pointée par le premier pointeur ?

Hors ligne

 

#4 01-10-2008 08:43:21

Cortex  
Modérateur
Lieu: Arlon
Date d'inscription: 08-02-2008
Messages: 194
Pépites: 6,904
Banque: 2,109,818,425,070

Re: Correspondance de type char** entre DLL C++ et PowerBuilder

Nyphel a écrit:

Autant je comprends bien l'idée de la première solution, autant j'ai du mal à saisir la seconde. La méthode me retournerait en fait l'adresse pointée par le premier pointeur ?

Pour info alors (puisque ca ne corrige pas ton problème), il arrive parfois que certains outils de dev (souvent PB et VB6.0), suite à une particularité de leur gestion mémoire, aient du mal sur certaines variables de type tableau de char (le cas ici) ou des tableaux de structures complexes. J'ai par exemple eu le coup dans des API pour imprimantes, quand on veut récupérer la liste des imprimantes installées, etc...
Le but du code est en effet de récupérer le pointeur de la chaine produite par ton API, et de demander à PB de la convertir en string... Mais c'est quand même assez dangereux, faut pas commencer à jouer dans PB avec ce pointeur ;)

Et pour en revenir à ton problème, sans doc, il y a peu de chance de trouver ce qui cloche...

Hors ligne

 

#5 08-10-2008 14:58:50

Nyphel  
Membre Power Geek
Lieu: Grenoble
Date d'inscription: 06-05-2008
Messages: 253
Pépites: 12
Banque: 529,705,333,097,693

Re: Correspondance de type char** entre DLL C++ et PowerBuilder

Des informations complémentaires sont disponibles ici !

Hors ligne

 

#6 04-11-2008 16:55:51

Nyphel  
Membre Power Geek
Lieu: Grenoble
Date d'inscription: 06-05-2008
Messages: 253
Pépites: 12
Banque: 529,705,333,097,693

Re: Correspondance de type char** entre DLL C++ et PowerBuilder

J'ai pu obtenir de la documentation sur le sujet, et il m'est demandé d'utiliser la fonction DecryptAESFile(...) d'une DLL externe, plutôt que la précédante fonction GetDecryptedFile() de l'objet COM.

La DLL que j'utilise est écrite en C, et est encodée ANSI.

DWORD DecryptAESFile(IN char * szFilePath, OUT UCHAR ** ppcDecryptedData, OUT DWORD * pdwDecryptedSize)
- Decrypt the aes-encrypted file (defined with szFilePath) into the ppcDecryptedData buffer of size equal to pdwDecryptedSize.

Je déclare donc ma fonction externe comme suit :

Code: pb

FUNCTION long DecryptAESFile(string szInputFile, ref string pcDecryptedFileContents, ref ULong dwDecryptedContentsSize) LIBRARY "Csr_PicDEC.dll" alias for "_DecryptAESFile@12;Ansi"


Puis je l'utilise comme ceci :

Code: pb

string ls_test_encrypted_picture, ls_test_DecryptedContents
ULong ll_test_DecryptedContentsSize
blob lb_test_decrypted_content
ls_test_encrypted_picture = "C:\CSR\EXE\2-encrypted.jpg"

// Décrypte le contenu d'un fichier image crypté
// ls_test_DecryptedContents est géré par la fonction (allocation de mémoire, affectation du contenu texte décrypté), 
// ll_test_DecryptedContentsSize : longueur du texte décrypté
DecryptAESFile(ls_test_encrypted_picture, ls_test_DecryptedContents, ll_test_DecryptedContentsSize)

messagebox('1', string(ll_test_DecryptedContentsSize)) // Me retourne 7200
messagebox('2', string(ls_test_DecryptedContents)) // Me retourne 4 caractères bizarres et aléatoires

// Affichage de l'image dans un PictureControl
lb_test_decrypted_content = blob(ls_test_DecryptedContents) 
p_test.setpicture(lb_test_decrypted_content)

// Enregistrement de l'image décryptée dans un fichier
integer li_FileNum
li_FileNum = FileOpen("D:\PICTURE.JPG", LineMode!, Write!, LockWrite!, Replace!)
FileWrite(li_FileNum, ls_test_DecryptedContents)
FileClose(li_FileNum)


Il semblerait donc que j'accède bien à la fonction de ma DLL.
Cette dernière décrypte correctement l'image puisqu'elle me retourne la longueur de la chaine décryptée (7200).
En revanche je n'accède pas correctement au résultat, on dirait que j'accède au pointeur...

J'avoue que j'ai du mal à ce niveau. Une idée ?

Dernière modification par Nyphel (04-11-2008 17:13:17)

Hors ligne

 

#7 05-11-2008 07:36:42

buck  
Modérateur
Lieu: Dijon
Date d'inscription: 31-07-2008
Messages: 747
Pépites: 1,028,843
Banque: 171,170,849,654

Re: Correspondance de type char** entre DLL C++ et PowerBuilder

Bonjour,

Tu as la réponse dans une autre de tes discussions : http://pbadonf.fr/forum/viewtopic.php?id=1956

A mon point de vue : uchar ** => ref byte ppcDecryptedData[]

Si byte est indisponible sur ta version, tu peux utiliser long à la place http://www.sybase.com/detail?id=44648.

Hors ligne

 

#8 05-11-2008 08:23:46

Nyphel  
Membre Power Geek
Lieu: Grenoble
Date d'inscription: 06-05-2008
Messages: 253
Pépites: 12
Banque: 529,705,333,097,693

Re: Correspondance de type char** entre DLL C++ et PowerBuilder

Bonjour Buck, et merci pour ce rappel. Bien que j'essaie de reprendre les posts de façon aussi claire que possible, je m'y perds parfois moi-même

Le type Byte est en effet indisponible sur ma version, et les tableaux de long/char n'apportent pas plus de résultats.

Essai n°1 : j'obtiens une série de 8 chiffres dans ll_test_DecryptedContents

Code: pb

FUNCTION long DecryptAESFile(string szInputFile, ref long pcDecryptedFileContents[], ref ULong dwDecryptedContentsSize) LIBRARY "Csr_PicDEC.dll" alias for "_DecryptAESFile@12;Ansi"

Code: pb

string ls_test_encrypted_picture, ls_test_DecryptedContents
ULong ll_test_DecryptedContentsSize
long ll_test_DecryptedContents[]
char lc_test_DecryptedContents[]

ls_test_encrypted_picture = "C:\CSR\EXE\2-encrypted.jpg"

// Décrypte le contenu d'un fichier image crypté
// ls_test_DecryptedContents est géré par la fonction (allocation de mémoire, affectation du contenu texte décrypté), 
// ll_test_DecryptedContentsSize : longueur du texte décrypté
DecryptAESFile(ls_test_encrypted_picture, ll_test_DecryptedContents, ll_test_DecryptedContentsSize)


Essai n°2 : j'obtiens quelques étranges caractères dans lc_test_DecryptedContents

Code: pb

FUNCTION long DecryptAESFile(string szInputFile, ref char pcDecryptedFileContents[], ref ULong dwDecryptedContentsSize) LIBRARY "Csr_PicDEC.dll" alias for "_DecryptAESFile@12;Ansi"

Code: pb

string ls_test_encrypted_picture, ls_test_DecryptedContents
ULong ll_test_DecryptedContentsSize
long ll_test_DecryptedContents[]
char lc_test_DecryptedContents[]

ls_test_encrypted_picture = "C:\CSR\EXE\2-encrypted.jpg"

// Décrypte le contenu d'un fichier image crypté
// ls_test_DecryptedContents est géré par la fonction (allocation de mémoire, affectation du contenu texte décrypté), 
// ll_test_DecryptedContentsSize : longueur du texte décrypté
DecryptAESFile(ls_test_encrypted_picture, lc_test_DecryptedContents, ll_test_DecryptedContentsSize)


Bref j'ai l'impression que j'accède au pointeur, mais pas à la chaine pointée.

Hors ligne

 

#9 05-11-2008 08:29:49

erasorz  
Admin
Lieu: Babylone
Date d'inscription: 23-11-2006
Messages: 5121
Pépites: 97,197
Banque: 2,147,483,647

Re: Correspondance de type char** entre DLL C++ et PowerBuilder

et si tu fais un String( ls_chaine, 'address' )


N'envoyez jamais un humain faire le travail d'un programme.

Hors ligne

 

#10 05-11-2008 08:49:57

Nyphel  
Membre Power Geek
Lieu: Grenoble
Date d'inscription: 06-05-2008
Messages: 253
Pépites: 12
Banque: 529,705,333,097,693

Re: Correspondance de type char** entre DLL C++ et PowerBuilder

Je viens de tester cela Erasorz, mais sans succès.

Pour un paramètre de type tableau de long, alors le "String(parametre_rempli_par_DLL, 'address')" me retourne une chaine vide.
Pour un paramètre de type tableau de char, alors le "String(parametre_rempli_par_DLL, 'address')" me retourne "address".
Pour un paramètre de type string, alors le "String(parametre_rempli_par_DLL, 'address')" me retourne "address".

Hors ligne

 

#11 05-11-2008 09:26:14

buck  
Modérateur
Lieu: Dijon
Date d'inscription: 31-07-2008
Messages: 747
Pépites: 1,028,843
Banque: 171,170,849,654

Re: Correspondance de type char** entre DLL C++ et PowerBuilder

Bonjour,

Il faut peut être réserver l'espace mémoire avant d'appeler la fonction.

Pour faire un test :

Code: pb

ll_test_DecryptedContents[10000] = 0

Hors ligne

 

#12 05-11-2008 09:32:24

Nyphel  
Membre Power Geek
Lieu: Grenoble
Date d'inscription: 06-05-2008
Messages: 253
Pépites: 12
Banque: 529,705,333,097,693

Re: Correspondance de type char** entre DLL C++ et PowerBuilder

Que mes tableaux soient initialisés ou pas, j'obtiens les mêmes résultats.
Idem lorsque j'utilise "String(parametre_rempli_par_DLL, 'address')".

:-/

Hors ligne

 

#13 05-11-2008 14:42:22

Nyphel  
Membre Power Geek
Lieu: Grenoble
Date d'inscription: 06-05-2008
Messages: 253
Pépites: 12
Banque: 529,705,333,097,693

Re: Correspondance de type char** entre DLL C++ et PowerBuilder

Je viens de relire ceci dans la documentation :

DWORD DecryptAESFile(IN char * szFilePath, OUT UCHAR ** ppcDecryptedData, OUT DWORD * pdwDecryptedSize)
- Decrypt the aes-encrypted file (defined with szFilePath) into the ppcDecryptedData buffer of size equal to pdwDecryptedSize.

Je n'avais pas pris garde au type UCHAR**, j'agissais comme si il s'agissait d'un type CHAR**.

Voici ce que dit la documentation MSDN au sujet du type UCHAR :

A UCHAR is an 8-bit integer with the range: 0 through 255 decimal. Because a UCHAR is unsigned, its first bit (Most Significant Bit (MSB)) is not reserved for signing.

Je ne comprends pas la logique, puisque l'objectif de cette fonction est de me retourner le contenu texte d'une image JPEG décryptée : ce texte devrait certainement être codable sur 7 bits, donc sur du char, si il utilise les normes classiques. En tous cas il semblerait que Powerbuilder n'aie pas de type équivalant au UChar*.

Je vais essayer d'obtenir plus d'informations sur le sujet.

Dernière modification par Nyphel (06-11-2008 08:47:23)

Hors ligne

 
  • Index
  •  » Powerscripts
  •  » Correspondance de type char** entre DLL C++ et PowerBuilder

Pied de page des forums

Propulsé par FluxBB 1.2.22