【发布时间】:2019-02-25 16:40:45
【问题描述】:
我正在开发一个 Delphi 项目。它是一个调用计算引擎(在 Delphi 中)的应用程序,该引擎从 Oracle 数据库中检索数据。该项目有效,但我在调试时遇到了麻烦。
为了调试引擎,我用计算引擎的 dll 创建了一个 COM 对象;我让应用程序调用本地主机(即在我的 COM 对象中运行的引擎)。然后我从代码中启动引擎(在 IDE 中按 Start),并启动调用引擎的应用程序。它通常像一个魅力一样工作——代码在我在引擎代码中设置的断点处停止。
但是几天以来,每次我尝试这样做时,都会收到一条由 Dataset.State=dsInactive 事实生成的错误消息。不过,我没有更改代码中的任何内容;在数据库和我的计算机之间打开了流程(我 ping 和 telnet 都可以)。
你知道什么会导致这个问题吗?
非常感谢您的帮助!
编辑 1: 非常感谢 MartynA 的回答!
你所描述的确实是我想说的——至少在开始时:我确实将生成 .dll 的项目加载到 IDE 中,编译它并放置一个断点,但我的断点是出现错误信息:
procedure TRNParameters.SetDataset(ADataset: TClientDataSet);
begin
if ADataset = nil then
TRNException.RaiseTechnicalException('Erreur à la création de l''objet TRNParameters : le dataset des paramètres est nil');
if ADataset.State = dsInactive then
TRNException.RaiseTechnicalException('Erreur à la création de l''objet TRNParameters : le dataset des paramètres est fermé');
我收到的消息是第二条消息,并且确实到达了该行上的断点 - 代码进入那个“如果” - 就在显示消息之前的那一刻。
我检查了调用堆栈,我得到了:
URNParams.TRNParameters.SetDataset($31345F0)
URNParams.TRNParameters.Create(???,nil)
SCEPlgFRObjectImpl.TSCEPlgFRObject.MtsDataModuleCreate(???)
:02ce0a2a TDataModule.DoCreate + $2E
:02ce086c TDataModule.Create + $E0
:02d31b70 TRemoteDataModule.Create + $38
:02d792af TComponentFactory.CreateComObject + $F
:02ccda34 TComObjectFactory.CreateInstance + $1C
:02d79211 TComponentFactory.CreateInstance + $C5
:75c58bc6 ; C:\windows\syswow64\ole32.dll
:75c73060 ; C:\windows\syswow64\ole32.dll
:7662a419 ; C:\WINDOWS\SysWOW64\COMSVCS.DLL
:7662ad82 ; C:\WINDOWS\SysWOW64\COMSVCS.DLL
:7662adf9 ; C:\WINDOWS\SysWOW64\COMSVCS.DLL
:7662ae0f ; C:\WINDOWS\SysWOW64\COMSVCS.DLL
:7662aea1 ; C:\WINDOWS\SysWOW64\COMSVCS.DLL
:7662af94 ; C:\WINDOWS\SysWOW64\COMSVCS.DLL
:765d93ca ; C:\WINDOWS\SysWOW64\COMSVCS.DLL
:765d93aa ; C:\WINDOWS\SysWOW64\COMSVCS.DLL
:7666b7ee ; C:\WINDOWS\SysWOW64\COMSVCS.DLL
:7666b9d2 ; C:\WINDOWS\SysWOW64\COMSVCS.DLL
:76271287 msvcrt._itow_s + 0x4c
:76271328 msvcrt._endthreadex + 0x6c
:7594343d kernel32.BaseThreadInitThunk + 0x12
:778e9802 ntdll.RtlInitializeExceptionChain + 0x63
:778e97d5 ntdll.RtlInitializeExceptionChain + 0x36
所以我猜问题来自 SCEPlgFRObjectImpl.TSCEPlgFRObject.MtsDataModuleCreate(???) 行。所以我在 MtsDataModuleCreate 中放了一个断点,最终得到了更准确的错误信息:
try
OraSessionFRA_SPU.Open;
except
on e: Exception do
begin
WriteLog('SCEPlgFR - ConnectDatabase : ConnectString=' + OraSessionFR_SPU.ConnectString);
WriteLog('SCEPlgFR - ConnectDatabase : ' + e.Message);
raise Exception.Create('SCEPlgFR - ConnectDatabase : ' + #13#10 + e.Message);
end;
end;
但是!消息无法访问(由于优化)! 你知道我怎么能读到那条消息吗?
另外,我不知道如何找到 COM 对象的创建位置,它是应该在我的 Delphi 代码中的一段代码吗? (对不起,我对 Delphi 和 COM 对象很陌生!)
非常感谢您的帮助!
编辑 2
大家好,
我创建了一个字符串变量 Mess 并添加了一个 Mess:=e.Message 来捕获错误消息。我得到一个“ORA-12154:TNS:无法解析指定的连接标识符”。
我想我能从中找到出路。 非常感谢MartynA,你是我的超级英雄!
编辑 3 大家好, 这是问题的解决方案:我的 Delphi 找不到具有所需连接的 TNS。 (可能是因为我必须进行冲突安装来开发与不同 Oracle 飞行员一起工作的不同软件)。 所以数据集无法打开的原因是因为无法连接到数据库(因为无法访问正确的 TNS)。一位同事让我创建了一个 TNS_ADMIN 环境变量,该变量的路径指向所需的 TNS。它解决了我的问题。
再次感谢您的帮助!
【问题讨论】:
-
COM 对象通常托管在您的本地计算机上。如果是,您应该能够在 IDE 中发现错误(请参阅我尝试的答案);如果不是,您是否尝试过使用远程调试器?顺便说一句,哪个操作系统和 Delphi 版本?
-
很高兴您找到了解决方案。现在您知道了,可能值得花一点时间在调试器上,看看您是否最终能找到它。
-
是的,好主意,我一定会这样做的!
标签: oracle delphi debugging com dataset