sp40
Messages postés1276Date d'inscriptionmardi 28 octobre 2003StatutContributeurDernière intervention 3 juillet 2015
-
25 juil. 2012 à 10:37
sp40
Messages postés1276Date d'inscriptionmardi 28 octobre 2003StatutContributeurDernière intervention 3 juillet 2015
-
27 juil. 2012 à 17:40
Bonjour,
Je suis sur un dev client-serveur Firebird avec Delphi XE2, en utilisant Datasnap. Je rencontre des difficultés pour passer un objet (tstrings par exemple) du serveur au client.
Pour expliquer un peu mieux, sur le serveur, j'ai une methode getList qui fait un select d'un champ sur une table et retourne au client les valeurs dans un tstrings.
J'ai essayé de plusieurs façons :
1 - TStrings en retour
function getList : TStrings;
- Creation du Result (TStringList.Create)
- Creation dynamique IBSQL (select) et remplissage Result
-> Fonctionne quand j'appelle la methode à partir du client (ListBox.Items.AddStrings(Server.getList)), mais fuite mémoire sur le serveur dans la mesure où le "Result" de la fonction getList n'est pas libéré sur le serveur. De plus, à la fermeture du client, j'ai un runtime error 204 si je fais un seul appel à la fonction, runtime error 216 si j'en fais plus d'un...
2 - TStrings en paramètres par valeur ou par variable
Procedure getList(slRetour : TStrings); ou Procedure getList(var slRetour : TStrings);
- Creation dynamique IBSQL (select) et remplissage slRetour
Sur le passage par valeur, ça ne fonctionne pas et j'ai "operation de pointeur incorrecte"
Sur le passage par variable, qui me semble la façon la plus propre (mais est-ce qu'on peut faire un passage par variable d'un client à un serveur...), ça fonctionne la première fois, mais j'ai "operation de pointeur incorrecte" à la fermeture de l'appli (runtime error 204), au second appel, j'ai un message "Interne : le type tkPointer n'est actuellement pas supporté"
C'est dommage parce que le Datasnap, ça a l'air vraiment bien pensé... Je ne sais pas si je ne programme pas comme il faut ou si le problème vient d'XE2. J'ai trouvé ça sur le net (https://forums.embarcadero.com/thread.jspa?messageID=426045), j'ai modifié le fichier en question, recompilé mon client et mon serveur, mais ça n'a rien changé.
Avez-vous déjà rencontré ce problème ? (et surtout comment l'avez-vous solutionné ?)
informatixo
Messages postés129Date d'inscriptionmercredi 4 février 2004StatutMembreDernière intervention25 juillet 20121 25 juil. 2012 à 18:46
Bonsoir à tous,
J'arrive un peu tard visiblement mais bon ça peut être utile je pense vu qu'il s'agit du même cas de figure (XE2 / datasnap / Firebird 2.5).
Pour passer un objet du serveur au client, il nous a été conseillé par embarcadero de le serialiser/deserialiser à l'aide de JSON quand cela concerne des objets ou des types de données spécifique. En utilisant une unité commune entre le client et le serveur quand il s'agit de type de données personnalisés afin que JSON sache comment le sérialiser/désérialiser. Il y a un tutoriel sur le net la dessus si mes souvenirs sont bons !
Voilà j'espère avoir pu faire avancer le schmilblik !
sp40
Messages postés1276Date d'inscriptionmardi 28 octobre 2003StatutContributeurDernière intervention 3 juillet 201515 27 juil. 2012 à 17:40
Alors, on avance...
Pour le problème "erreur distante : erreur DBX : le pilote n'a pas été correctement initialisé. La bibliothèque est manquante, n'est pas correctement installée, sa version est incorrecte, ou le pilote n'est pas dans le chemin système" : J'ai réinstallé FireBird 2.5, et recopié le fbClient.dll dans le dossier sysWOW64. J'y ai aussi mis le dbxfb.dll ainsi que les fichiers midas.* trouvés dans le dossier embarcadero. Et là, merveille, j'affiche le dataset dans le client !!!
Reste le souci de fuite memoire pour les fonctions qui retournent un objet...
ThierryLaborde
Messages postés91Date d'inscriptionmercredi 12 septembre 2007StatutMembreDernière intervention23 janvier 20171 26 juil. 2012 à 13:20
Bonjour,
Si le but c'est d'envoyer une liste de chaine de caractères pourquoi ne pas utiliser un TJsonArray.
Côté serveur :
function TServerMethods1.ListeString: TJSONArray;
var
JsonArray:TJSONArray;
Liste:TStringList;
i: Integer;
begin
Liste:= TStringList.Create;
// Remplissage de la liste....
JsonArray:=TJSONArray.Create;
for i := 0 to Liste.Count-1 do
begin
JsonArray.Add(Liste[i]);
end;
Result:=JsonArray;
end;
Et côté client (Dans l'exemple je met le résultat dans une listbox) :
procedure TForm1.Button1Click(Sender: TObject);
var
ServerDs:TServerMethods1Client;
JsonArray:TjsonArray;
i:integer;
begin
ServerDs: =TServerMethods1Client.Create(SqlConnection1.DBXConnection);
JsonArray:=ServerDs.ListeString;
for i := 0 to JsonArray.Size-1 do
begin
ListBox1.Items.Add(JsonArray.Get(i).Value);
end;
end;
sp40
Messages postés1276Date d'inscriptionmardi 28 octobre 2003StatutContributeurDernière intervention 3 juillet 201515 25 juil. 2012 à 11:22
Bonjour Cantador,
Pas de problème avec Firebird (et même 2.5 ). J'ai des methodes du serveur qui retournent des strings et qui marchent sans aucun problème... Visiblement c'est dès que je veux faire passer des objets (ici des strings) que ça bloque...
sp40
Messages postés1276Date d'inscriptionmardi 28 octobre 2003StatutContributeurDernière intervention 3 juillet 201515 25 juil. 2012 à 15:15
Je vais utiliser le composant datasetprovider, qui permet d'accéder à distance à un dataset, mais je pensais que pour optimiser, ça aurait été plus rapide de passer un tstrings qu'un dataset... tant pis. Merci quand même pour tes interventions Cantador et à la prochaine.
sp40
Messages postés1276Date d'inscriptionmardi 28 octobre 2003StatutContributeurDernière intervention 3 juillet 201515 25 juil. 2012 à 16:50
Bé moi non plus... ça m'aurait bien arrangé de passer un tstrings, mais bon. Je vais essayer de poser la question. Ceci dit, il y a un tuto chez eux qui reprend le code que je voulais utiliser (celui avec la fuite mémoire...)
Du coup, je m'intéresse aux datasetprovider. Pas évident...
sp40
Messages postés1276Date d'inscriptionmardi 28 octobre 2003StatutContributeurDernière intervention 3 juillet 201515 27 juil. 2012 à 11:17
Bonjour et merci pour vos réponses.
à tlaborde :
Je veux bien essayer avec un JSONArray. Mais à priori, la liste créée côté serveur n'est pas libérée ("Liste:=TStringList.Create;
), ni le jsonarray (dans la mesure où il peut être libéré, je ne sais pas, mais dans le code serveur, il y a bien un "JsonArray:=TJSONArray.Create;"). Dans ce cas, on aura encore une fuite mémoire sur le serveur et autant retourner directement la liste en résultat de la fonction (fuite mémoire pour fuite mémoire, autant coder plus simplement )
Par ailleurs, je rencontre également des difficultés avec le groupe de composants SQLConnection + DSProviderConnection + ClientDataset.
Sur le serveur (machine : windows server 2008 r2), j'ai un SQLConnection, un DatasetProvider (exported = true) et un SQLDataset. Sur le client (machine : Xp pro sp3), je peux connecter le SQLConnection, le dsProviderConnection, mais dès que je veux connecter le ClientDataset, j'ai un message "erreur distante : erreur DBX : le pilote n'a pas été correctement initialisé. La bibliothèque est manquante, n'est pas correctement installée, sa version est incorrecte, ou le pilote n'est pas dans le chemin système".
"Distante", je suppose que ça signifie que l'erreur vient du serveur. Sur le serveur, j'ai copié dans system32 (vu que le serveur est une appli win32) le fichier "C:\Program Files\Embarcadero\RAD Studio\9.0\Redist\win32\dbxfb.dll" en provenance de mon poste de dev (config actuelle). J'ai essayé toutes les combinaisons (fichier "C:\Program Files\Embarcadero\RAD Studio\9.0\Redist\win64\dbxfb.dll" et repertoire serveur "sysWOW64"), rien n'y fait. J'ai également essayé avec Firebird 2.5 (64 bits et 32 b), firebird 2.1 (32 b) et firebird 2.0, sans succès... Avez-vous déjà rencontré le problème ? Y a t'il une manipulation à faire avec cette dll dbxfb.dll ?
sp40
Messages postés1276Date d'inscriptionmardi 28 octobre 2003StatutContributeurDernière intervention 3 juillet 201515 27 juil. 2012 à 11:27
ah oui, j'ai oublié ! Un autre souci : si je fais un serveur avec authentification (id et password), l'assistant de création du module client datasnap me bloque sur l'authentification car il prend l'ID pour le mot de passe. Si je veux utiliser l'assistant, je suis obligé de "désécuriser" mon serveur le temps de la création du client datasnap...