Karena kebutuhan proyek, saya menggunakan Delphi untuk menulis DLL yang menghubungkan database untuk mengekspor data ke file SQL, yang menggunakan komponen tadoquery.
Hanya ada satu metode ekspor:
fungsi dataExport (path, INI_PATH: PCHAR): Integer;
Setelah menulis, saya menulis test.exe dengan Delphi untuk pengujian dan menemukan bahwa itu dapat digunakan secara normal.
Kemudian dia menyerahkan DLL kepada rekannya dan memintanya untuk memanggilnya di PowerBuilder. Setelah meminumnya, kolega saya menemukan bahwa begitu DataExportPB dipanggil, dilaporkan bahwa DLL target tidak dapat dibuka. Saya pikir itu mungkin karena lingkungan yang berjalan di kedua sisi berbeda, jadi saya menyalin tes.exe dan mencobanya. Anehnya, test.exe berjalan dengan baik.
Untuk menentukan di mana masalahnya benar -benar terjadi, saya menggunakan Python dan C# untuk mengujinya lagi.
Coinitialize () tidak disebut
Setelah meninjau informasi, saya menemukan bahwa jika komponen ADO digunakan dalam DLL Delphi, maka metode Coinitialize ActiveX perlu dipanggil sebelum digunakan. Setelah mengetahui masalahnya, itu menjadi lebih mudah.
Saya pikir PowerBuilder harus baik -baik saja, tetapi siapa yang tahu itu akan menjadi masalah yang sama. Saya tidak bisa mengetahuinya sekarang. Modul CTYPES dalam Python menggunakan metode panggilan dalam C dan metode passing parameter harus sama dengan powerbuilder, tetapi mengapa masih tidak mungkin di PB? Kolega saya meminta saya untuk menulis metode output tambahan di DLL untuk mencobanya.
Tes Fungsi: PCHAR;
Mulai
Hasil: = 'Test String dari Test';
akhir;
Metode pengujian berhasil dipanggil di PB, dan kemudian kolega mencoba menelepon DataExport lagi, dan itu berhasil! Lai ? ? Mengapa? Metode pengujian ini hanya menghasilkan string tetap. Saya sangat bingung.
Tetapi masalah lain terjadi pada saat ini.
Saya dengan hati -hati memeriksa kode Delphi dan mengetahui menggunakan gambar apakah itu tidak dirilis.
fungsi dataExport (path, INI_PATH: PCHAR): Integer;
var
Kueri: Tadoquery;
Mulai
.........
Coinitialize ();
kueri: = tadoquery.create (nil);
.........
query.close;
query.free;
CounInitialize ();
.........
akhir;
Tidak ada yang salah! Dalam keputusasaan, saya membagi coinitialize () dan couninitialize () menjadi dua metode independen.
Fungsi init: integer;
Mulai
mencoba
Coinitialize ();
Hasil: = 1;
kecuali
pada pengecualian:
Hasil: = 0;
akhir;
akhir;
fungsi uninit: integer;
Mulai
mencoba
CounInitialize ();
Hasil: = 1;
kecuali
pada pengecualian:
Hasil: = 0;
akhir;
akhir;
Kemudian biarkan kolega memanggil init terlebih dahulu dalam acara inisialisasi formulir, dan kemudian tutup acara untuk menghubungi Uninit. Masalah terpecahkan. Semuanya normal.
Meskipun masalahnya telah diselesaikan, saya masih tidak mengerti mengapa saya melakukan ini.