代码之家  ›  专栏  ›  技术社区  ›  David Mohaimin Moin

我需要知道从C++ Builder 2007升级到2010的复杂应用程序?

  •  3
  • David Mohaimin Moin  · 技术社区  · 15 年前

    我公司的主要应用程序大多是用C++编写的(带有一些Delphi代码和组件)。我们将从RADStudio2007升级到2010,下一个版本将在大约一周后开始。为了确保升级顺利进行,我需要知道什么?

    到目前为止,我想到的要点是:

    • Unicode。这一个看起来 真的? 复杂的。我们的应用程序包含了一个可怕的std::string-s和ansistring-s的混合体,以及它们之间的强制转换。关于这个问题,我有很多问题,比如“WString能够保持所有的UnoDeString都可以,我们应该做一个搜索/替换”,还是“我们应该完全避免所有的C++字符串类型并使用UnoDeString”,“我们可以改变所有的事件处理程序使用字符串,虽然现有的。 .水电站 事件处理程序方法原型被编译器翻译成了ansistring“,从根本上来说,比如“我们应该给所有字符串加上L前缀,还是编译器足够聪明,允许使用Unicode字符串”,等等。任何有关这方面的见解都会受到赞赏。

      我们还需要向后兼容性。我们的应用程序使用它自己的二进制元组格式,该格式当前将字符串存储为字节数组。我需要升级它来读取旧文件,并且,大概还需要编写新的Unicode字符串。如何处理嵌入二进制格式的Unicode字符串?有没有什么通用的方法可以让我将一个unicodestring指向一个字节数组,这个数组最初可以写成ansi字节或unicode字节,然后它就会知道它们是什么?

    • 第三方组件。我们使用 SpTBX 主要是,而且似乎是兼容的。

    • 项目升级。codegear论坛中的标准建议似乎是在升级时手动重新创建所有项目文件。这是一个非常多的工作(7个项目(主要是libs)在我们的主应用程序,加上六个dll,一个 许多 有什么方法可以自动完成这个过程吗?

    • 链接器看起来怎么样?传统上,我们在链接器随机崩溃或资源耗尽方面遇到了很多麻烦,尽管在2007年它得到了很大改善。这就是我们的主应用程序拆分为多个libs的原因之一——链接器不能(希望“不能”,但现在可以“?”否则处理。

    • 我知道有一个新的类型库编辑器和格式(它存储IDL、IE文本,并动态生成TLB?)这对用TLB升级现有COM项目有多大的帮助?我们有Delphi代码和TLB,它们内置在C++应用程序中。

    • 我还有什么需要考虑或注意的吗?

    我发现:

    4 回复  |  直到 8 年前
        1
  •  4
  •   Moritz Beutel    15 年前

    项目升级。codegear论坛中的标准建议似乎是在升级时手动重新创建所有项目文件。这是一个非常多的工作(7个项目(主要是libs)在我们的主应用程序,加上六个dll,许多文件)有没有任何方法可以自动化这一点?

    有:只需使用IDE的项目导入器:)
    说真的,我只是试着导入项目,然后去调查它是否似乎不起作用。

    链接器看起来怎么样?传统上,我们在链接器随机崩溃或资源耗尽方面遇到了很多麻烦,尽管在2007年它得到了很大改善。这就是我们的主应用程序拆分为多个libs的原因之一——链接器不能(希望“不能”,但现在可以“?”否则处理。

    自从C++Builder 2009以来,我几乎不再遇到ILink了。我偶尔读到有人遇到内存不足的错误,但新闻组中有人发现了一种解决方法:

    https://forums.embarcadero.com/thread.jspa?messageID=140012&tstart=0#140012

    还有,你可以读到 here 编译器得到了一个新选项(-cx)来控制它分配的最大内存量。

    我知道有一个新的类型库编辑器和格式(它存储IDL、IE文本,并动态生成TLB?)这对用TLB升级现有COM项目有多大的帮助?

    应该可以毫无障碍地工作。

    我有很多关于这个的问题,比如“wString是否能够容纳unicodeString所能容纳的一切,我们是否应该进行搜索/替换?”

    是的,在Windows平台上,wchar_t通常是16位大的,这意味着它足以容纳unicodestring是的utf-16。

    还是“我们应该完全避免所有C++字符串类型并使用UnoDeString”

    取决于代码的可移植性。在任何情况下,只要您只需要字符串类型,就使用“string”,而不是“unicodestring”。

    “我们是否可以将所有事件处理程序更改为使用字符串,尽管现有的.hpp已被编译器转换为ansisting”

    首先,您不应该重复使用由旧版本的DCC生成的.hpp文件! 对于在Delphi中使用字符串类型的事件处理程序,必须使用UnicodeString。如上所述,只需使用“String”,您的代码就可以用于C++ Builder的ANSI和Unicode版本。

    从根本上来说,比如“我们应该给所有字符串加上L前缀,还是编译器足够聪明,允许使用Unicode字符串?”

    编译器不会转换字符串(这会与语言标准冲突),但ansistring和unicodestring都有char*和wchar_t*字符串文本的复制构造函数重载。也就是说,以下内容将起作用:

    AnsiString as = L"foo";
    UnicodeString us = "bar";
    

    但是,这种方式不起作用的是整个printf()/scanf()函数;ansistring::sprintf()接受const char*,unicodestring::sprintf()接受const wchar_*。

    如果您经常使用sprintf(),您可能会发现我的cbdeformat库很有用;只需阅读 my article on the subject .

        2
  •  2
  •   IanH    15 年前

    您没有说明二进制元组格式的数据字符串的用途:它们是否需要存储Unicode?当我从d2007转换到d2009时,我只能保留系统ansi字符串的某些部分。

    如果需要存储Unicode,则需要检查现有数据是否与UTF-8等格式兼容。如果存储在现有数据文件中的值的范围存在问题,那么我将让您的下一次升级对任何旧数据文件进行一次性转换,读取旧的ansisting数据并将其作为utf-8写回其他文件名或扩展名,或者修改适当的文件头数据。我已经对数据文件进行了很长时间的版本控制,只是为了允许这种处理更改。

    我只是在启动一个BCB2010项目,所以不能对您的其他问题发表评论,但我确实很难将Delphi项目从D2007升级到D2009,尽管我可以通过编辑项目文件来解决这个问题,该文件只是XML。

    祝你在转化过程中好运;-)

        3
  •  2
  •   Remy Lebeau    15 年前

    Unicode。这个看起来真的 复杂的。我们的应用程序包含 std::string-s和 与演员之间的转换 他们。我有很多问题 这,比如“是我们所能做到的 把所有的东西都放在一个单码串里 可以,我们应该做一个 搜索/替换

    std::wstring 包含 wchar_t* 弦,就像 System::UnicodeString 做。

    我们应该避免所有的C++字符串吗? 全部输入并使用 单列字符串

    这由你决定。 char* 仍然支持字符串。您不必强制将所有内容迁移到Unicode。

    我们可以将所有事件处理程序更改为 通过现有的.hpp使用字符串 编译器是否翻译成了ansistring?

    不,不能将自动管理的事件处理程序更改为使用 System::String 别名。所有的IDE版本都会抱怨这一点。您必须手动更新事件处理程序声明和实现才能使用 UnicodeString 参数而不是 AnsiString 适当时的参数。这也意味着您不能在多个IDE版本之间共享dfm和unit.h文件(无论如何都不应该这样做)。

    我们应该在所有字符串前面加上l, 或者编译器是否足够聪明 已启用Unicode以使用Unicode字符串

    不可以。如果声明一个字符串常量或不带L前缀的字符常量,数据仍将被解释为ANSI。这并没有改变。但是,您可以将ANSI数据传递给 系统::unicodestring (但不 STD:: ,它将自动转换为Unicode。但是您必须小心,因为它将使用操作系统的默认ansi代码页来解释数据。只要您的ANSI数据只使用ASCII字符,那么您就可以了。否则,如果您使用的是非ASCII字符,那么最好将数据放入 System::AnsiStringT System::RawByteString (这两个都是在CB2009中引入的)已经分配了正确的代码页,然后将其分配给 系统::unicodestring 变量。转换将使用关联的代码页而不是操作系统默认代码页。

    我们还需要向后兼容性。 我们的应用程序使用自己的二进制元组 当前存储字符串的格式 作为字节数组。我需要 升级此文件以读取旧文件, 可能,编写新的Unicode字符串 也。如何处理Unicode 以二进制格式嵌入的字符串?

    如果元组需要8位字符,则必须确保任何结构声明和此类声明都使用 char 而不是 wchar_t 字符。如果需要存储Unicode字符串,但需要保持8位兼容性,则应首先将Unicode字符串编码为UTF-8(可以使用 System::UTF8String 字符串类型来帮助您-从CB2009开始,它现在是一个真正的UTF-8字符串)。只要您不使用非ASCII字符,那么您的旧应用程序就不会知道区别,因为ASCII字符是按UTF-8编码的。但是,如果您想要存储原始的Unicode数据,那么您的tuple将需要一个标志(如果它还没有标志)来指示字符串数据是以ansi还是unicode存储的,并且您的应用程序必须查找该标志。

    有什么通用的方法吗 将一个unicodestring指向 字节,可以最初写入 作为ANSI字节或Unicode,以及 它会知道它们是什么?

    不,您必须事先知道字节的实际编码。如果您将内存地址传递给 System::AnsiString std::string ,它将采用ANSI字符。如果您将相同的内存地址传递给 系统::unicodestring STD:: ,它将采用Unicode字符。

    第三方组件。我们使用SPTBX 主要是,看起来 兼容的。

    就像所有以前的版本一样(除了从2006年到2007年的迁移),您拥有的任何第三方组件都需要为2010年重新编译,要么手动(如果您有它们的源代码)要么由它们各自的供应商重新编译。

    项目升级。标准建议 在codegear论坛上 手动重新创建所有项目文件 升级时。

    对。这仍然适用。

    我知道有一个新的类型库 编辑器和格式(它存储IDL, IE文本,并生成TLB 动态地?)

    .tlb文件不再使用。新系统现在操作.ridl(reduced idl)文件。在编译期间,.ridl直接在可执行文件的二进制资源中生成正确的类型库信息。没有生成.tlb文件。

    这对升级有多好 有TLB的现有COM项目?我们 有Delphi代码和TLB 内置到C++应用程序中。

    我不记得CB2010(或CB2009,就此而言)是否可以直接使用预先存在的.tlb文件。我觉得他们做不到。但是,您可以通过tlibmp.exe运行.tlb文件,它将导出.ridl文件。或者,您可以在以前的版本中从TLB编辑器复制IDL文本,并手动将其粘贴到新的.ridl文件中。无论哪种方法,您都可以将该.ridl文件添加到CB2010项目中。

    2007年和2010年共存。我不是 当然,我相信这个答案,因为我 2006年和2007年在 以前是同一台机器。

    这就是为什么我在同一台物理计算机上安装多个IDE版本时使用虚拟机的原因。

        4
  •  1
  •   zproxy    15 年前

    升级的成本是否与收益相符?

    为什么不在新平台上开发新组件的地方开始逐步升级呢?通过不同的互操作助手将新组件集成到旧版本。

    This approach was suggested to vb6 developers who were thinking about upgrading to vb.net .