如何解决“加载了两个不同的 CRTLDLL”问题在 C++ 中使用包时建造者2010?

发布于 2024-09-06 15:33:25 字数 2394 浏览 6 评论 0原文

我们正在尝试将整体 EXE 拆分为一个 EXE 和多个包的组合。到目前为止,我们尝试使用一个包,并且在运行 EXE Codeguard 时在启动时显示以下错误:

CG Error

Two different CRTLDLLs are loaded. CG might report false errors
(C:\Windows\system32\CC32100MT.DLL)
(D:\Projects\Foo\Bar.bpl)

OK   

我将其读为正在加载的两个不同的运行时库 - 一个是正确的(CC32100MT.dll),有一个不正确,这是我们正在尝试使用的包。

继续运行程序会出现奇怪的错误,特别是在类之间进行转换或将指向类的指针作为跨 EXE/DLL 边界的方法中的参数传递。不过,Codeguard 本身根本不显示任何其他错误。 编辑:此问题现已解决,并且不相关。程序看起来运行正常,但 Codeguard 显示的警告仍然令人担忧。

我们如何解决这个问题?

更多细节

我们已经研究了我们(从事此工作的开发人员和我)可以共同想到的尽可能多的事情:

  • 每个项目都是使用运行时包构建的。 EXE 主机在其包列表中列出了 Bar。

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

  • 包通过其 BPI 文件链接到 EXE,但通过 LIB 链接也没有区别。

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

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

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

  • 创建一个新项目(一个普通的 VCL 表单应用程序)并链接到 BPL(通过其 BPI)效果很好。在添加所有文件和 LIB 的过程中,使我们的 EXE 包含更改此设置所需的代码,但我们无法弄清楚是什么。

    • 所有的 LIB 要么对应于我们使用的 DLL(平面 C 接口,通常看起来像是用 MSVC 构建的),要么是包含大量相关文件的简单项目,编译为 lib 以便链接到EXE - 顺便说一句,这些大致对应于我们想要拆分为 BPL 的程序区域。 LIB 项目似乎没有会影响 RTL 链接的项目选项,除非我们错过了它们。

    • 我已经详尽地搜索了Depends,并查看了所有 RTL 和 CC32*.dll 文件、EXE 以及每个 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。目前还没有修复,但警告似乎并不表明存在真正的问题(即,它可能是一个虚假错误,虽然遗憾的是运行时必须单击跳过该对话框,但愿错误中没有什么值得担心的。)

We are trying to split up our monolithic EXE into a combination of an EXE and several packages. So far, we have one package that we're trying to use, and when running the EXE Codeguard shows the following error on startup:

CG Error

Two different CRTLDLLs are loaded. CG might report false errors
(C:\Windows\system32\CC32100MT.DLL)
(D:\Projects\Foo\Bar.bpl)

OK   

I read this as two different runtime libraries being loaded - one, the correct one (CC32100MT.dll), one incorrect, which is the package we're trying to use.

Continuing to run the program shows odd errors, especially casting between classes or passing a pointer to a class as a parameter in a method that crosses the EXE/DLL boundary. Codeguard itself doesn't show any other errors at all though. Edit: This is now resolved, and wasn't related. The program appears to run correctly, but the warning Codeguard shows is still worrying.

How do we solve this?

Some more details

We've looked at as many things as we (the developer working on this and I) can collectively think of:

  • Each project is built using runtime packages. The EXE host lists Bar in its package list.

  • Each project is set to compile with dynamic RTL. However, changing this does not solve the problem.

  • The package is linked to the EXE via its BPI file, but linking via a LIB makes no difference either.

  • The EXE and BPL are compiled with the same project settings, where the same options exist for both types of project. We think, anyway :)

  • There is only one copy of the BPL and BPI on the system: it's definitely linking to the right one.

  • Examining the EXE and BPL with Depends and TDump show they are both using C:\Windows\system32\CC32100MT.DLL. They should both be using the one RTL.

  • Creating a new project (a plain VCL forms application) and linking to the BPL (via its BPI) works fine. Something in the process of adding all the files and LIBs that make our EXE contain the code it needs to changes this, but we haven't been able to figure out what.

    • The LIBs all either correspond to DLLs we use (flat C interface, usually look as though they were built with MSVC) or are simple projects with lots of related files, compiled to a lib for the purpose of linking into the EXE - these correspond roughly to the areas of the program we want to split to BPLs, by the way. There don't seem to be project options for the LIB projects that would affect RTL linking, unless we've missed them.

    • I have exhaustively hunted through Depends and looked at all RTL and CC32*.dll files the EXE and every single DLL references. All are identical: rtl140.bpl and CC32100MT.DLL. Fully qualified paths show they are the same files, too. Everything should be using the one same run-time library.

Edit: The final EXE is complex, built with several libs, several DLLs, etc. All these, when built with C++Builder, are built with the current version. Is it possible there's something in one of these DLLs or LIBs that could cause a problem? I don't know enough about how the RTL is linked in to be sure about where to look... my (naive?) assumption is that the linker would normally link in one set of RTL functions, but that of course doesn't seem to be happening... and I don't know how things change when using packages. Is it possible this error has always existed and Codeguard has not flagged it before, because we haven't used something dynamic like a package?

Perhaps another question is, Why would a package have its own RTL anyway, or what would make it count as 'a RTL DLL' to Codeguard?

We're stumped. Absolutely stumped. We've had other problems using BPLs (they seem to be surprisingly tricky things, especially using C++) but have managed to solve them all. This one we've had no luck at all and we'd really appreciate any insights :)

We're using C++Builder 2010 (as part of RAD Studio actually, but with little Delphi code apart from components.)

Edit: Started a bounty. I'd really like to solve this!

Edit 2: Thanks to David Dean for his help (marked as answered below.) Via email, he pointed out this issue was reproduced in a simple test case by someone else, and is logged in Embarcadero QC as report 86335. Currently there is no fix, but the warning does not appear to indicate a genuine problem (ie, it's probably a spurious error, and while it's a pity to have to click past the dialog when you run, hopefully there's nothing in the error to worry about.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦在深巷 2024-09-13 15:33:25

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

Since one of these is coming from a .bpl, did you try turning off "Build with runtime packages" in the project options?

音盲 2024-09-13 15:33:25

我们也有类似的问题。我们追踪到一个(非 VCL).cbproj,它是在没有“多线程”选项的情况下创建的。

据我所知,您唯一有机会设置此选项的是当您创建新的 .cbproj 时,此后无法使用 GUI 更改它。我们最终“破解”了 .cbproj 以包含以下内容:

<Multithreaded>true</Multithreaded>

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

We had a similar problem. We tracked it down to a (non VCL) .cbproj that was created without the "Multithreaded" option.

As far as I can tell, the only time you get chance to set this option is when you create a new .cbproj, it cannot be changed afterwards using the GUI. We ended up "hacking" the .cbproj to include the following:

<Multithreaded>true</Multithreaded>

To determine which dll is causing the issue, it should be the last dll loaded in the output window just before you see the CG message.

恋竹姑娘 2024-09-13 15:33:25

您是否检查过是否使用 _TCHAR 作为 char。我们在 RAD Studio 中遇到了一些类似的问题,我们找到了使用 _TCHAR 作为字符的解决方法。一旦使用 wchar_t 编译一个 DLL 或 BPL 项目,就会出现此代码防护错误。

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

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

Did you check if you use _TCHAR as char. We had some similar problems with RAD Studio and we found a workaround using _TCHAR as char. As soon as one DLL or BPL Project is compiled with wchar_t, this code guard error appears.

We also figured out, that EXE projects can be compiled with TCHAR = wchar_t without any problem (the main function will be WIDE).

The settings does not affect the GUI being able to handle UNICODE.

各空 2024-09-13 15:33:25

一位客户在我们的公共错误跟踪系统中记录了类似的案例,并且bug 已在最新版本中被识别并修复。

A customer logged a similar case in our public bug tracking system and the bug has been identified and fixed in the latest release.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文