otavioreis
Messages postés82Date d'inscriptionjeudi 5 avril 2007StatutMembreDernière intervention 4 mars 2008
-
16 avril 2007 à 23:14
otavioreis
Messages postés82Date d'inscriptionjeudi 5 avril 2007StatutMembreDernière intervention 4 mars 2008
-
19 avril 2007 à 14:17
Bonjour,
J'ai écrit une DLL en delphi. J'ai crée une autre application en Delphi pour accéder les fonctions de la DLL. ça marche bien. Maintenant il faut que j'appelle les fonctions de la DLL du VBA sur un fichier Excel. J'i bien declaré la fonction. ça ne marche pas. Vous savez pour quoi?
Voilà la fonction de la DLL sur Delphi:
function NU:string; stdcall;
var
Buffer : array[0..255] of char;
BufferSize : DWORD;
begin
BufferSize := sizeOf(Buffer);
GetUserName(@buffer, BufferSize);
Result:=Buffer;
end;
exports
NU;
Voilà ma declaration sur le VBA d'Excel:
Declare Function NU Lib "C:\PrjDllDelphi\PrjDllDelphi.dll" () As String
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 201413 19 avril 2007 à 08:43
Avec la traduction en Delphi peut être ?
Testée sous Word.
=====================================
library VBATest;
uses
windows, ActiveX;
function myGetUserName(): TBSTR; stdcall;
var
buffer: array[0..255] of Char;
size: Cardinal;
begin
size:= SizeOf(buffer);
GetUserName(buffer, size);
if size = 0 then buffer[0]:= #0;
Result:= SysAllocStringByteLen(buffer, size);
end;
exports
myGetUserName;
begin
end.
=====================================
Private Declare Function myGetUserName Lib "VBATest.dll" () As String
Private Sub CommandButton1_Click()
MsgBox myGetUserName
End Sub
=====================================
[troll]
Au passage, un peu de 'semi interprété' désassemblé :
add esp, $fffffefc ; Ceci n'est pas une allocation ^^
mov [esp], 100 ; Affectation de size
push esp ; On pousse l'adresse de size
lea eax, [esp+$08] ; Calcul de l'adresse du buffer
push eax ; On pousse l'adresse du buffer
call GetUserName
cmp dword ptr [esp], 0 ; Comparaison entre size et 0
jnz myGetUserName + $23 ; On saute si différent de 0
mov byte ptr [esp+$04], 0 ; On met 0 à la première case
mov eax,[esp] ; On met l'adresse de size dans eax
push eax ; On pousse l'adresse de size
call SysAllocStringByteLen
add esp, $104 ; dés(pas une allocation)
ret
otavioreis
Messages postés82Date d'inscriptionjeudi 5 avril 2007StatutMembreDernière intervention 4 mars 2008 16 avril 2007 à 23:48
Merci de la réponse... Mais cette DLL marche bien quand je l'appelle à partir des applications Delphi et C++. Elle ne marche pas seulement avec le VB.
C'est le pb était la pile, l'adresse serait invalide avec n'importe quel application, non?
peut être qu'il y a un pb avec la déclaration ,non?
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 17 avril 2007 à 00:00
Le prob n'est pas de déclaration mais de logique.
Delphi et C connaissent les pointeurs, VB que nenni donc impossible de lui en passer une autre que celle d'un BSTR.
Faut revoir tes notions d'informatique, on ne donne pas en sortie de fonction une adresse d'une variable locale, son contenu sera écrasé à tout coup dans les prochaines instructions.
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 201413 17 avril 2007 à 14:51
Le principal souci dans les appels de dll classique, c'est les allocations. Si tu alloue une chaîne dans une dll en C, avec un malloc par exemple, et que tu essaye de libérer tout ça dans une appli en Delphi, tu risque de gros problème. En effet, le gestionnaire de mémoire de Delphi ne comprendrat pas du tout d'où sort le pointeur.
La ton tableau est effectivement alloué sur la pile : c'est joué avec le feu -> cela ne fonctionne que dans des cas particuliers.
Donc soit il faut allouer et libérer que d'un côté, soit il faut s'arranger pour que les deux côtés utilisent le même gestionnaire de mémoire (cf sharmem en Delphi par exemple, ou les Sys*String*).
Le plus simple dans ton cas est de suivre l'exemple du Win32, ou les allocations et libérations de ce genre de chaînes se font côté exe (Comme dans GetUserName par exemple ). Le pointeur sur la zone allouée et la taille de cette zone sont envoyés à la dll, qui remplit et vérifie que la zone est assez grande.
En VB, pour allouer un bout une chaîne d'une taille précise, soit on la remplie d'espaces :
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 17 avril 2007 à 19:02
"alloué sur la pile" est déjà un abus de langage ce qui induit les incompréhensions. Il n'y a aucune allocation pour une variable locale mais un simple retrait du registre ESP, celui ci étant replacé en sortie de fonction il est tout à fait clair que ça ne peut jamais fonctionner puisque la zone de pile peut se faire réécrire à tout moment.
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 17 avril 2007 à 21:42
Tu vois un rapport avec ça ???
BSTR __stdcall bnGetUsername()
{
char buff[264];
DWORD len;
len = GetUserName(buff, 260);
buff[len] = 0;
return SysAllocStringByteLen(buff, len);
}
moi aucun.
Il faut allouer une String avec une des fonctions de la famille SysAllocString() !!!
Laisse ton Delphi et fais en C, on sort la dll en 2.5 Ko. Si c'est pour fournir à un inbterprété du code dll en semi interprété, aucun intérêt, autant faire depuis VB.
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 17 avril 2007 à 21:51
Bonsoir, otavioreis,
Tu sais quoi ?
Quand je relis ceci, signé Renfield :
Environ$("UserName")
et que je vois ton acharnement à alourdir ainsi ton appli avec une fonction Delphi pour faire ce qui est déjà une fonction VB faisant parfaitement cette toute petite chose
j'ai vraiment envie de pleurer....
J'ose espérer que ta Dll écrite en Delphi n'utilise pas un composant écrit en VB faisant lui-même appel à une fonction écrite en C; qui se servirait d'une fonction d'une des librairies de l'API de Windows !!! (Quien sabe ?)