C++ VS2005 中的静态字符 * vs #define

Posted

技术标签:

【中文标题】C++ VS2005 中的静态字符 * vs #define【英文标题】:static char * vs #define in C++ VS2005 【发布时间】:2010-08-06 17:16:13 【问题描述】:

我有一个大型程序,其中包含几个使用 MFC 和 /clr 编译的大型 DLL。程序集中有 65535 个全局 FieldRVA 条目的限制。如果更多,则加载程序引发异常。我已经启用字符串池 (/GF)。

我有很多类似的代码:

static char *pSTRING_ONE = "STRING_ONE";

如果我使用宏进行编译,例如:

#define pSTRING_ONE  "STRING_ONE"

它大大减少了 CLR 元数据的字符串,因此我进行了编译,但随后我得到了使用 #define 的所有问题。

问题是:除了更改静态字符 * -> #define 之外,还有其他选择吗?

【问题讨论】:

您在使用#define 时遇到的具体问题是什么? 问题在于宏可以重新定义。我也不确定对程序大小的影响。 【参考方案1】:

来自 MSDN:

http://msdn.microsoft.com/en-us/library/s0s0asdt.aspx

“/GF 编译器选项为每个唯一字符串创建一个可寻址部分。默认情况下,一个目标文件最多可以包含 65,536 个可寻址部分。如果您的程序包含超过 65,536 个字符串,请使用 /bigobj 编译器选项来创建更多部分。”

听起来 /bigobj 是你的朋友...

【讨论】:

不确定这是解决方案。程序集/ DLL 中的条目数似乎有问题。尝试在运行时加载程序集/DLL 时引发异常。不是编译时间。【参考方案2】:

与其将字符串存储在程序的数据段中(因为您显然有大量字符串),不如拥有一个包含它们的资源文件。然后只需动态分配一个字符串池,并在程序启动时加载字符串资源文件。这应该可以完全消除问题。

如果这不是一个选项,假设它们包含在文件范围内,为什么要创建字符串 static?这只是说“仅文件范围”的 C 方式(在 C++ 中已弃用)。 const char *pSTRING_ONE = "STRING_ONE"; 将创建一个在所有翻译单元之间共享的全局字符串。在这种情况下,麻烦的是只创建一个包含所有字符串的文件,然后通过标题中的 extern 声明来引用它们。

如果您不使用/GF 会怎样?从 Bukes 的回答看来,通过汇集字符串,您会导致编译器为每个字符串创建一个段。

【讨论】:

我同意长期调整这些字符串和变量的代码(它们是表字段名称和大小)是最好的长期方法。然而,这个遗留系统有数百个字段,跨越一百多个表,并从数百个源文件中引用。所以我一直在寻找更快的解决方案......【参考方案3】:

不幸的是,我们问题的最佳解决方案是在一个类中包含有问题的代码。

// Old Way
static char *pSTRING_ONE = "STRING_ONE";

新的

class CFieldDefs

  public:
     static char *pSTRING_ONE;


char *CFieldDefs::pSTRING_ONE = "STRING_ONE";

用法:

CFieldDefs:pSTRING_ONE;

尽管更改相当乏味,但它大大减少了 DLL 中 fieldRVA 条目 CLR 字段的数量。感谢您的所有帮助。

【讨论】:

以上是关于C++ VS2005 中的静态字符 * vs #define的主要内容,如果未能解决你的问题,请参考以下文章

VS2008(C++)-控制台项目中LNK2005错误的问题

在将大型 C++ 程序从 VS2005 转换为 VS2008 之前我应该​​知道啥?

将 C++ 从 VS2003 迁移到 VS2005 需要哪些代码更改?

将解决方案 C++ 从 VS2005 升级到 VS2012 出现错误 LNK1181

在 Windows 中将 VS2005 静态库与 gcc 链接

我想问一下vs 2008中的头文件的问题啊