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