Debido a las necesidades del proyecto, utilicé Delphi para escribir una DLL que conecta la base de datos para exportar los datos al archivo SQL, que utiliza el componente TadoQuery.
Solo hay un método de exportación:
function dataExport (ruta, ini_path: pchar): integer;
Después de escribir, escribí un test.exe con Delphi para las pruebas y descubrí que podría usarse normalmente.
Luego entregó la DLL a su colega y le pidió que lo llamara en PowerBuilder. Después de tomarlo, mi colega descubrió que una vez que se llama a DataSexportPB, se informa que la DLL objetivo no se puede abrir. Creo que podría deberse a que los entornos que se ejecutan en ambos lados son diferentes, por lo que copié el test.exe y lo probé. Curiosamente, Test.exe funciona bien.
Para determinar dónde ocurre realmente el problema, utilicé Python y C# para probarlo nuevamente.
Coinitialize () no se llama
Después de revisar la información, descubrí que si el componente ADO se usa en la DLL de Delphi, entonces se debe llamar al método de Coinitialize de ActiveX antes de usar. Después de conocer el problema, se vuelve mucho más fácil.
Pensé que PowerBuilder debería estar bien, pero quién sabía que sería el mismo problema. No puedo entenderlo ahora. El módulo CTypes en Python usa el método de llamada en C y el método de aprobación de parámetros debe ser el mismo que PowerBuilder, pero ¿por qué todavía no es posible en PB? Mi colega me pidió que escribiera un método de salida adicional en DLL para probarlo.
Prueba de función: PCHAR;
Comenzar
Resultado: = 'Test String from test';
fin;
El método de prueba se llamó con éxito en PB, y luego el colega intentó volver a llamar a DataSexport, ¡y fue exitoso! ! ? ? ¿Por qué? Este método de prueba solo genera una cadena fija. Estoy realmente perplejo.
Pero se produjo otro problema en este momento.
Verifiqué cuidadosamente el código Delphi y descubrí la figura si no fue lanzado.
function dataExport (ruta, ini_path: pchar): integer;
varilla
Consulta: tadoQuery;
Comenzar
.........
Coinitialize ();
consulta: = tadoQuery.create (nil);
.........
Query.close;
consulta.
Couninitialize ();
.........
fin;
¡No hay nada malo! En desesperación, dividí coinitialize () y Countinitialize () en dos métodos independientes.
función init: integer;
Comenzar
intentar
Coinitialize ();
resultado: = 1;
excepto
En la excepción:
resultado: = 0;
fin;
fin;
función uninit: entero;
Comenzar
intentar
Couninitialize ();
resultado: = 1;
excepto
En la excepción:
resultado: = 0;
fin;
fin;
Luego deje que el colega llame a Init primero en el evento de inicialización del formulario y luego cierre el evento para llamar a UNITIT. Problema resuelto. Todo es normal.
Aunque el problema se ha resuelto, todavía no entiendo por qué hago esto.