在我正在编写的组件中,我想包含automatic detection of registered image formats,但这是一个仅在禁用“使用调试DCU的编译器”选项时有效的解决方案。

我真正想知道的是这种解决方案的替代方案,它不涉及编译器选项依赖性。

但是暂时,我只想知道如何在运行时检查是否设置了“使用调试DCU的编译器”选项。

最佳答案

没有可靠的方式在运行时获取该信息

Use Debug DCUs编译器选项仅切换搜索路径;编译器最终将找到的内容未知。一个(被误导的)用户可能已经在调试目录上复制了发行版dcu,反之亦然。

即使没有错误的用户,也可能会有一些文件添加到项目中(并随项目一起编译),以便包含一些错误修复程序。例如,如果用户将Graphics.pas添加到项目中,则进行发布/无调试构建,但保留Use Debug DCU's编译器选项,则实际上链接的Graphics.dcu不是调试构建,因为它是用可执行文件重新构建。因此,您得到了“混合”的调试和非调试dcus包。

您可以尝试检测与某些对象或方法有关的调试信息的存在,但这也将是不可靠的:如果您使用“ Build with Debug Dcus”,但将“ Debug Information”设置为false,则实际上是在丢弃调试信息,以便您不再寻找它。

但是该链接代码在Debug DCU上失败

来自GLScene项目的代码不是一个很好的技巧,它在TPicture.RegisterFileFormat的代码中使用硬编码的偏移量,然后继续使用硬编码的偏移量来获取全局FileFormats变量的地址(不是调用GetFileFormats例程)。里面的魔法数字太多了!

我的第一个操作是将使用TList方法识别的GLScene与我已经识别的TList进行比较,但是猜猜是什么:在我的机器上,在两种情况下,两个例程都得到了相同的结果。在我的计算机上,GLScene看上去很丑,但并没有用调试DCU破坏。

我什至尝试对某些rtl / vcl单元(SysUtils,Graphics,Classs)进行“指纹识别”。我列出了所有公共类的清单,生成了一些对每个类中的每个方法使用RTTI的代码,并将代码的前1024个字节转储到字符串文件中。用Debug DCU和非Debug DCU运行该程序,我得到了相同的结果。我的文本文件包含3500种方法的指纹!

这不是一个好主意

由于该选项并没有真正影响编译器的编译方式(仅影响链接器链接的内容),因此创建依赖于此选项的代码非常不可靠,也不是一个好主意。这只会影响低级黑客,并且您不希望在绝对无法控制的情况下使您的应用程序崩溃的低级黑客。

唯一正确的选择是用不会失败(或至少以可控制的方式失败)替换潜在失败的黑客。

09-25 15:31