Delphi - 在连接到 Oracle 并调用 Web 服务方法后关闭时 ntdll.dll 中的异常
Posted
技术标签:
【中文标题】Delphi - 在连接到 Oracle 并调用 Web 服务方法后关闭时 ntdll.dll 中的异常【英文标题】:Delphi - Exception in ntdll.dll on closing after both connection to Oracle and calling a web service method 【发布时间】:2012-10-17 22:14:16 【问题描述】:在 Delphi 2009 中,我发现每当我执行 both 到 Oracle 的连接(通过 OCI.dll)和对 Web 服务方法的调用时,我都会在 ntdll.dll 中遇到异常在 IDE 中关闭我的应用程序时。
对于与 Oracle 的连接,我尝试使用 DOA(直接 Oracle 访问)4.1.1.0 和 ODAC 组件(最新试用版);
对于 Web 服务方法调用(只是一个简单的“函数 HelloWorld:字符串”),在从 Web 服务导入 WSDL 之后,我正在使用 Delphi 的库存功能。
如果我在“直接”模式下使用 ODAC 组件,即不使用 OCI.dll,则关闭时不会出现异常。
如果我只调用 Web 服务方法(不连接到 Oracle),则关闭时不会发生异常(即使我使用 DOA 或 ODAC 组件)。
如果我只连接到 Oracle(通过 OCI.dll)(不调用 Web 服务方法),一切都会正常(无论我使用 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 表单应用程序
在表单上放置一个 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),然后关闭表单。
【问题讨论】:
没有任何代码或任何重现方式都无法解释。请给我们一些可以合作的东西。 我会在完全调试模式下使用 FastMM 来获取有关内存损坏的一些信息。此外,madExcept 等工具可以为您提供有用的堆栈跟踪。 不是一个解决方案,但您可以尝试: 1) 不同的初始化顺序 - 首先是 OCI,然后是 WebServ,然后是向后。 2) 通过包围 WSAStartup / WSACleanup 的 OCI 和 WebServ 调用来显式控制 Winsock。 3) 这可能是一个“DLL 地狱”问题 - 查看仅由 OCI 和仅由 WebServ 加载的 DLL。 【参考方案1】:鉴于这可能是“DLL 地狱”问题,我能够在 Windows XP 和 Vista 上运行测试:一切正常。所以我开始认为这个问题一定与 Windows 7 上的 Delphi 2009 有关。
我是对的,我发现 Delphi 2009 在 Windows 7 上调试存在问题。
幸好有补丁可用:
ID: 27476, Hotfix 2 for Delphi 2009 and C++Builder 2009
应用补丁解决了!
【讨论】:
以上是关于Delphi - 在连接到 Oracle 并调用 Web 服务方法后关闭时 ntdll.dll 中的异常的主要内容,如果未能解决你的问题,请参考以下文章