Из -за потребностей проекта я использовал Delphi, чтобы написать DLL, который подключает базу данных для экспорта данных в файл SQL, который использует компонент Tadoquery.
Есть только один метод экспорта:
Функция DataExport (Path, Ini_path: pchar): целое число;
После написания я написал Test.exe с Delphi для тестирования и обнаружил, что его можно использовать нормально.
Затем он передал DLL своему коллеге и попросил его позвонить в PowerBuilder. После этого мой коллега обнаружил, что как только DataExportPB называется, сообщается, что целевой DLL не может быть открыт. Я думаю, что это может быть потому, что среды, работающие с обеих сторон, разные, поэтому я скопировал Test.exe и попробовал его. Как ни странно, test.exe работает нормально.
Чтобы определить, где на самом деле возникает проблема, я использовал Python и C#, чтобы проверить его снова.
Coinitialize () не называется
После просмотра информации я обнаружил, что если в DLL в DLL -DLPH используется компонент ADO, то перед использованием необходимо вызвать метод ActiveX Coinitialize. Узнав проблему, это становится намного проще.
Я думал, что PowerBuilder должен быть в порядке, но кто знал, что это будет та же проблема. Я не могу понять это сейчас. Модуль CTYPES в Python использует метод вызова в C, а метод передачи параметров должен быть таким же, как PowerBuilder, но почему он все еще невозможно в PB? Мой коллега попросил меня написать дополнительный метод вывода в DLL, чтобы попробовать его.
Функциональный тест: pchar;
Начинать
Результат: = 'Тестовая строка из теста';
конец;
Метод испытаний был успешно назван в PB, а затем коллега попытался снова вызвать DataExport, и это было успешным! ! ? ? Почему? Этот метод испытаний просто выводит фиксированную строку. Я действительно озадачен.
Но в настоящее время возникла другая проблема.
Я тщательно проверил код Delphi и обнаружил, что он не был выпущен.
Функция DataExport (Path, Ini_path: pchar): целое число;
вар
Запрос: Tadoquery;
Начинать
.........
Coinitialize ();
запрос: = tadoquery.create (nil);
.........
Query.close;
Query.free;
COUNTINITAILIZE ();
.........
конец;
Нет ничего плохого! В отчаянии я разделял Coinitialize () и Countinitialize () на два независимых метода.
Функция init: целое число;
Начинать
пытаться
Coinitialize ();
результат: = 1;
кроме
на исключение:
Результат: = 0;
конец;
конец;
Функция нежна: целое число;
Начинать
пытаться
COUNTINITAILIZE ();
результат: = 1;
кроме
на исключение:
Результат: = 0;
конец;
конец;
Затем пусть коллега сначала позвонит в событие инициализации формы, а затем закройте событие, чтобы вызвать Uninit. Проблема решена. Все нормально.
Хотя проблема была решена, я до сих пор не понимаю, почему я это делаю.