当在C++ Builder 2010中使用包时,如何解决“加载了两个不同的CRTLDLLs”的问题?

4
我们正在尝试将我们的单体EXE拆分成一个EXE和几个包的组合。到目前为止,我们有一个我们正在尝试使用的包,当运行EXE时,Codeguard在启动时显示以下错误:
CG错误
已加载两个不同的CRTLDLL。CG可能会报告虚假错误 (C:\ Windows \ system32 \ CC32100MT.DLL) (D:\ Projects \ Foo \ Bar.bpl)
好的
我理解为加载了两个不同的运行时库-一个是正确的(CC32100MT.dll),另一个是错误的,这是我们正在尝试使用的包。
继续运行程序会显示奇怪的错误,特别是在跨越EXE / DLL边界的方法中将类之间进行强制转换或将类的指针作为参数传递。 但Codeguard本身并没有显示任何其他错误。
我们该如何解决这个问题?
一些更多的细节
我们已经看了很多东西,我们(开发人员和我)可以共同思考:
  • 每个项目都使用运行时包进行构建。 EXE主机在其包列表中列出了Bar。

  • 每个项目都设置为使用动态RTL进行编译。但更改此设置并不能解决问题。

  • 该包通过其BPI文件与EXE链接,但通过LIB进行链接也没有任何区别。

  • EXE和BPL使用相同的项目设置进行编译,两种类型的项目都存在相同的选项。我们认为是这样的 :)

  • 系统上只有一个BPL和BPI副本:它肯定连接到正确的副本。

  • 使用DependsTDump检查EXE和BPL,显示它们都正在使用C:\ Windows \ system32 \ CC32100MT.DLL。它们应该都使用同一个RTL。

  • 创建一个新项目(纯VCL窗体应用程序)并通过其BPI链接到BPL可以正常工作。添加所有文件和LIB的过程中使我们的EXE包含所需代码的过程中发生了一些变化,但我们无法弄清楚原因。

    • LIBs都对应于我们使用的DLL(平坦的C接口,通常看起来像是使用MSVC构建的),或者是具有许多相关文件的简单项目,编译为lib以便链接到EXE中 - 顺便说一下,这些大致对应于我们想要拆分为BPL的程序区域。除非我们错过了它们,否则不会影响RTL链接的LIB项目的项目选项。

    • 我已经在Depends中进行了详尽的搜索,并查看了EXE和每个DLL引用的所有RTL和CC32 * .dll文件。所有内容都是相同的:rtl140.bpl和CC32100MT.DLL。完全限定的路径显示它们是相同的文件。一切都应该使用同一个运行时库。

编辑:最终的EXE比较复杂,构建时使用了多个库文件和DLL文件等。所有这些都是用当前版本的C++Builder构建的。有没有可能其中一个DLL或LIB文件会引起问题?我对RTL的链接方式不太了解,不确定该在哪里查找……我的(天真的?)假设是链接器通常会链接一组RTL函数,但显然并没有发生这种情况……而且我也不知道使用包时会发生什么变化。这个错误是否一直存在,只是因为我们还没有使用像包这样的动态东西,所以Codeguard没有标记出来?
也许另一个问题是,为什么一个包会有自己的RTL,或者什么会使它被Codeguard视为“一个RTL DLL”呢?
我们陷入了困境。非常困惑。我们在使用BPL时遇到了其他问题(特别是使用C++时似乎非常棘手),但我们已经成功解决了所有问题。这一个我们完全没有进展,我们真的很感激任何见解 :)
我们正在使用C++Builder 2010(实际上是RAD Studio的一部分,但除了组件之外几乎没有Delphi代码)。

编辑: 开始了一项悬赏。我真的想解决这个问题!

编辑2: 感谢David Dean的帮助(在下面标记为已回答)。通过电子邮件,他指出这个问题由其他人在一个简单的测试案例中复制,并在Embarcadero QC上作为报告86335记录。目前还没有修复,但警告似乎并不表示有真正的问题(即,它很可能是一个虚假的错误,虽然运行时必须点击过对话框,但希望错误中没有什么可担心的东西。)


似乎没有针对LIB项目的项目选项会影响RTL链接,除非我们错过了。我相信TLib选项中有一个“使用动态RTL”的开关。请确保已选中它。此外,在不使用CodeGuard构建时它能正常工作吗? - Moritz Beutel
“Use dynamic RTL” 已被选中。即使未使用 Codeguard,它似乎也无法正常工作。 - David
4个回答

1

由于其中一个来自.bpl文件,您是否尝试在项目选项中关闭“使用运行时包构建”?


在EXE项目选项中吗?不,这并不能解决问题。在包项目选项中,复选框被禁用,因此既无法选择也无法取消选择,并且文本字段为空。 - David
您明确声明:每个项目都使用运行时包构建。EXE主机在其包列表中列出了Bar。您在哪里看到这个? - David Dean
抱歉,我的意思是每个具有运行时包选项的项目都是使用运行时包构建的。 当我写下这句话时,我可能认为BPL也是如此,这让人感到困惑!BPL不是这样的,链接到EXE中的LIB甚至没有此选项,而是EXE有此选项。 关闭EXE对此没有任何影响。 “Where”在“项目选项”,“包”项,“使用运行时包构建”复选框和其下方的文本框中。 BPL应该具有此选项吗?此对话框中是否存在控件但被禁用会造成问题? - David
链接器的命令行是什么样的,用于生成可执行文件(exe)?你应该在消息视图的“输出”选项卡中看到这个。 - David Dean
我看到足够的信息表明它确实在尝试使用动态RTL和BPL进行链接,但是它在静态链接VCL。在exe的项目选项中查看“使用运行时包构建”的复选框下面的行,如果它没有至少“vcl、rtl、vclx、foo”,那么你可能会遇到不匹配的问题,因为有些是静态链接而其他一些是动态链接。 - David Dean
显示剩余8条评论

1
我们曾经遇到过类似的问题。我们追踪到一个(非VCL).cbproj文件,它是在没有选择“多线程”选项的情况下创建的。
据我所知,您唯一有机会设置此选项的时间是在创建新的.cbproj时,无法使用GUI后更改它。最终,我们“黑客式”地修改了.cbproj文件以包含以下内容:
<Multithreaded>true</Multithreaded>

为了确定哪个dll导致问题,应该在看到CG消息之前,最后加载的dll应该显示在输出窗口中。

谢谢您的建议!EXE项目没有这行代码,但仍然使用了多线程RTL DLL,并手动添加该行也没有改变任何东西。最后列出的DLL是UxTheme.dll,即Windows自带的一个DLL,我们大部分正常的DLL和包都在列表中较早地加载。虽然有几个DLL会在消息之后加载,例如VC编译的第三方DLL和sxs.dll。 - David

1

你有检查过是否使用了_TCHAR作为char吗?我们在RAD Studio中遇到了类似的问题,但是我们找到了一个解决方法,就是使用_TCHAR作为char。只要有一个DLL或BPL项目使用了wchar_t进行编译,就会出现这个代码保护错误。

我们还发现,EXE项目可以使用TCHAR = wchar_t进行编译而不会出现任何问题(主函数将是WIDE)。

这些设置不会影响GUI处理UNICODE的能力。


1
嗨,测试一下:是的,EXE和BPL都使用_TCHAR编译为wchar_t。不过还是感谢您的建议! - David

1
一位客户在我们的公共漏洞跟踪系统中记录了类似的问题,该漏洞已经在最新版本中得到修复。

那是C++ Builder XE吗,David? - David
1
是的,它已经在C++Builder XE中修复了。 - David Dean

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接