En raison des besoins du projet, j'ai utilisé Delphi pour écrire une DLL qui connecte la base de données pour exporter les données vers le fichier SQL, qui utilise le composant TADOCHERY.
Il n'y a qu'une seule méthode d'exportation:
fonction DataExport (chemin, ini_path: phar): entier;
Après avoir écrit, j'ai écrit un test.exe avec Delphi pour les tests et j'ai constaté qu'il pouvait être utilisé normalement.
Puis il a remis la DLL à son collègue et lui a demandé de l'appeler dans Powerbuilder. Après l'avoir pris, mon collègue a constaté qu'une fois DataExportPB, il est rapporté que la DLL cible ne peut pas être ouverte. Je pense que c'est peut-être parce que les environnements fonctionnant des deux côtés sont différents, j'ai donc copié le test.exe et l'ai essayé. Étrangement, Test.exe fonctionne bien.
Afin de déterminer où le problème se produit vraiment, j'ai utilisé Python et C # pour le tester à nouveau.
Coinitialize () n'est pas appelé
Après avoir examiné les informations, j'ai constaté que si le composant ADO est utilisé dans la DLL de Delphi, la méthode de monnaie d'ActiveX doit être appelée avant utilisation. Après avoir connu le problème, cela devient beaucoup plus facile.
Je pensais que Powerbuilder devrait aller bien, mais qui savait que ce serait le même problème. Je ne peux pas le comprendre maintenant. Le module CTYPES dans Python utilise la méthode d'appel en C et la méthode de passage des paramètres devrait être la même que PowerBuilder, mais pourquoi est-elle toujours possible dans PB? Mon collègue m'a demandé d'écrire une méthode de sortie supplémentaire en DLL pour l'essayer.
Test de fonction: PCHA;
Commencer
Résultat: = 'Test String From Test';
fin;
La méthode de test a été appelée avec succès dans PB, puis le collègue a essayé d'appeler DataExport à nouveau, et il a réussi! ! ? ? Pourquoi? Cette méthode de test sort simplement une chaîne fixe. Je suis vraiment perplexe.
Mais un autre problème s'est produit à ce moment.
J'ai soigneusement vérifié le code Delphi et j'ai découvert en utilisant la figure si elle n'a pas été publiée.
fonction DataExport (chemin, ini_path: phar): entier;
var
requête: Tadoquery;
Commencer
.........
Coinitialize ();
Query: = tadoquery.create (nil);
.........
query.close;
query.refree;
Counninitialiser ();
.........
fin;
Rien de mal! En désespoir de cause, j'ai divisé le Coins de Coinsiation () et le couninitialize () en deux méthodes indépendantes.
fonction init: entier;
Commencer
essayer
Coinitialize ();
Résultat: = 1;
sauf
À l'exception:
Résultat: = 0;
fin;
fin;
Fonction Uninit: entier;
Commencer
essayer
Counninitialiser ();
Résultat: = 1;
sauf
À l'exception:
Résultat: = 0;
fin;
fin;
Ensuite, laissez le collègue appeler init d'abord dans l'événement d'initialisation du formulaire, puis fermez l'événement pour appeler Uninit. Problème résolu. Tout est normal.
Bien que le problème ait été résolu, je ne comprends toujours pas pourquoi je fais cela.