Delphi - Исключение в ntdll.dll при закрытии после подключения к Oracle и вызова метода веб-службы
В Delphi 2009 я обнаружил, что каждый раз, когда я выполняю как соединение с Oracle (через OCI.dll), так и вызов метода веб-службы, я получаю исключение в ntdll.dll при закрытии приложения в IDE.
Для подключения к Oracle я попытался использовать компоненты DOA (Direct Oracle Access) 4.1.1.0 и ODAC (последняя пробная версия);
Для вызова метода веб-службы (просто "функция HelloWorld: строка") я использую стандартные возможности Delphi после импорта WSDL из веб-службы.
Если я использую компоненты ODAC в "прямом" режиме, то есть не использует OCI.dll, при закрытии не возникает никаких исключений.
Если я вызываю только метод веб-службы (без подключения к Oracle), при закрытии не возникает никаких исключений (даже если я использую компоненты DOA или ODAC).
Если я подключаюсь только к Oracle (через OCI.dll) (без вызова метода веб-службы), все тоже будет хорошо (независимо от того, использую ли я компоненты DOA или ODAC).
Один и тот же код отлично работает при выполнении как в Delphi 7, так и в Delphi XE2: исключение не происходит при закрытии приложения.
Некоторая информация: Delphi 2009 (стоковая версия и версия обновления 3) ОС: Windows 7 32-битный Oracle Instant Client 10.2.0.4 и Oracle Instant Client 10.2.0.5
Я начинаю подозревать, что это может быть проблема, связанная с повреждением кучи в Delphi 2009 при закрытии приложения...
Любая помощь, пожалуйста?
Шаги для воспроизведения (из комментария):
- Создать новое приложение VCL Forms
- Поместите компонент TOracleSession DOA (с именем OracleSession1) в форму
- Поместите TButton в форму (с именем Button1)
- Поместите этот обработчик события для события нажатия кнопки:
Вот код:
procedure TForm1.Button1Click(Sender: TObject);
var
MyWebService3Soap: WebService3Soap;
s: string;
begin
OracleSession1.LogonDatabase := 'SomeLogonDB';
OracleSession1.LogonUsername := 'SomeUsername';
OracleSession1.LogonPassword := 'SomePassword';
OracleSession1.Connected := True;
ShowMessage('Connected');
MyWebService3Soap := GetWebService3Soap();
s := MyWebService3Soap.HelloWorld(); // Just returns a string such as "Hello World"
ShowMessage(s);
end;
Интерфейс "WebService3Soap" - это интерфейс, автоматически генерируемый Delphi 2009 WSDL Importer. Вот значимая часть:
WebService3Soap = interface(IInvokable)
['{F6F12FA6-3881-8BB5-AD71-2408B47692CD}']
function HelloWorld: string; stdcall;
end;
function GetWebService3Soap(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): WebService3Soap;
initialization
InvRegistry.RegisterInterface(TypeInfo(WebService3Soap), 'http://mytest.it/Test3', 'utf-8');
InvRegistry.RegisterDefaultSOAPAction(TypeInfo(WebService3Soap), 'http://mytest.it/Test3/HelloWorld');
InvRegistry.RegisterInvokeOptions(TypeInfo(WebService3Soap), ioDocument);
end.
Запустите приложение внутри IDE, нажмите кнопку (закройте 2 следующих ShowMessages) и затем закройте форму.
1 ответ
Учитывая намек на то, что это может быть проблема с DLL-адом, я смог запустить тест как на Windows XP, так и на Vista: все прошло нормально. Поэтому я начал думать, что эта проблема как-то связана с Delphi 2009 в Windows 7.
Я был прав и обнаружил, что в Delphi 2009 существует проблема с отладкой в Windows 7.
К счастью, патч доступен:
ID: 27476, исправление 2 для Delphi 2009 и C++Builder 2009
Применение патча решено!