J'essaie d'utiliser une DLL C ++ à partir d'un programme natif. Je suis le scénario de méthode virtuelle comme expliqué ici
permet de dire ma signature de fonction C ++ est de la forme p> et la signature Delphi correspondante est p> et quelque part du programme Delphi, je peux appeler Le contrôle entre dans la DLL, mais SZIP et SZPort Les paramètres formels reçoivent uniquement le premier caractère de la propriété intellectuelle et du port que j'avais passé du programme Delphi. P> Je comprends que cela a à voir avec NULL, terminant correctement la chaîne à Delphi. Donc, j'avais essayé aussi ce qui suit. P> var
pzIp, pzPort: PChar;
szIp, szPort: string;
begin
szIp := '192.168.1.2';
szPort := '9777';
//initilize memory for pchar vars
GetMem(pzIp, Length(szIp)+1);
GetMem(pzPort, Length(szPort)+1);
//null terminate the strings
pzIp[Length(szIp)+1] := #0;
pzPort[Length(szPort)+1] := #0;
//copy strings to pchar
StrPCopy(pzIp, szIp);
StrPCopy(pzPort, szPort);
end.
3 Réponses :
Si je comprends bien, votre prototype de fonction doit également être aussi STDCALL.
function Setup(ip, port: PChar):Integer: virtual; stdcall; abstract;
Hmm, ça n'a pas fonctionné. Le même résultat. Mais je pourrais me débarrasser d'un accident de violation d'accès lorsque la fonction C ++ est renvoyée. Donc, je suppose que je fais des progrès :)
Il est temps de tomber à la vue de l'assemblage :)
le faire stdcall m'avait résolu quelques autres problèmes, +1 pour la pointe
est de la même taille dans les deux compilateurs? Si vous utilisez D2009 / D2010, Char est maintenant 16 bits. P>
Ouais j'utilise D2010. Et mon code C ++ est 32 bits. Donc, la taille du personnage doit correspondre à droite?
Pas nécessairement: BCB4 est un compilateur C ++ 32 bits, mais un article est un octet. Vous pouvez être null-terminer votre chaîne prématurément avec le 0 High-Byte pour le premier caractère. Essayez de changer votre code de test ci-dessus pour déclarer Szip et Szport en tant qu'Anstring au lieu de la chaîne.
dans Delphi 2010 (et Delphi 2009) Le type "Char" est en fait un widecharar - c'est-à-dire 16 bits de large. Ainsi, lorsque vous appelez votre fonction C ++, si cela s'attend à ce que cela soit de 8 bits de largeur (appelé «ANSI», plutôt que UNICODE), alors il va mal interpréter le paramètre d'entrée.
E.g. Si vous passez la chaîne mais parce que les 3 caractères de votre chaîne n'ont que des valeurs de point de code 8 bits ( En termes unicode, cela signifie que ce que le code C ++ "voit" est une chaîne qui ressemble à: p> ce qui expliquerait pourquoi votre code C ++ semble seulement obtenir le premier caractère de la chaîne - c'est voir le # 0 fort> dans le 2e 2e octet fort> de ce premier caractère et en supposant qu'il s'agisse du terminateur null pour toute la chaîne. P> Vous devez soit modifier votre code C ++ pour recevoir correctement les pointeurs sur signature de fonction révisée: p> et la "main longue" correspondante montrant la conversion de chaînes à ansistring fort > Avant d'appeler la fonction - le compilateur peut prendre en charge cela pour vous, mais vous trouverez peut-être utile de préciser votre code plutôt que de compter sur «Compiler Magic»: P> var
sIPAddress: ANSIString;
sPort: ANSIString;
begin
sIPAddress := '192.168.1.100';
sPort := '97777';
pObj.Setup(sIPAddress, sPort);
// etc...
Merci pour l'explication plus détaillée: ma réponse a été une pensée rapide qui s'est avérée juste, mais je le recommande comme la réponse à accepter.
Merci @deltics, ça a fonctionné. Un petit changement cependant, nécessaire pour être jeté pour rendre le programme Delphi compile POBJ.Setup (Pansichar (SIPADDRESS), PANSICHAR (SPORT)); Spécial merci à @ianh aussi