9

我有一个文件module.hpp

struct ModuleBase {
    virtual void run() = 0;
};

和一个main.cpp程序

int main() {
    cout << ...?...; // here should go the contents of module.hpp
}

我可以放什么...?...让头文件的内容在这里打印?

一个基本的想法是

int main() {
    static const string content = R"(
#include <module.hpp>
)";
    cout << content;
}

但是多行字符串仅在 C++11 中可用,并且在多行字符串中不起作用(这很好#include

如果 gcc 有一种不可移植的方式……那将是一个开始。

澄清(更新):替换应该在编译时完成。

4

4 回答 4

5

我知道的唯一真正的解决方案是编写一个小程序,将文件转换为包含它的字符串变量的 C++ 定义。这写起来相当简单:输出一个简单的标题,如下所示:

char const variableName[] =

然后复制文件的每一行,将其包装在 中"...\n",并转义任何必要的字符。(如果您可以确定 C++11,那么您也许可以用 做一些事情R"...",但我没有这方面的经验。)

[更新:参考带有错字的原始问题]: 您的解决方案不应该工作;如果是这样,那就是编译器中的错误。根据 §2.2,标记化发生 执行预处理指令之前。因此,当执行预处理指令时,您有一个字符串文字,而不是预处理#标记。(使用 C++11 功能时,编译器会出现错误。实现者还没有足够的时间来解决所有的错误。)

于 2012-12-20T11:19:26.067 回答
2

作为仅限 GNU 的 hack,您可以将标头转换为二进制对象文件并将其与可执行文件链接。

首先,用于objcopy进行转换:

objcopy -I binary -O default -B i386 module.hpp module.hpp.o 

如有必要,替换i386为您正在构建的架构。生成的目标文件将包含标头内容及其大小的符号,您可以按如下方式访问:

#include <iostream>

extern char _binary_module_hpp_start;
extern char _binary_module_hpp_size;

int main()
{
    char * header_start = &_binary_module_hpp_start;
    size_t header_size = reinterpret_cast<size_t>(&_binary_module_hpp_size);

    std::cout.write(header_start, header_size);
}
于 2012-12-20T13:16:31.160 回答
1

除了外部工具,我认为这是做不到的。您给出的 C++11 方式不起作用,#include未在字符串中展开。例如,请参见此处

C++03 方式如下,带有宏:

#define TO_STR__(...) #__VA_ARGS__
#define TO_STR_(...) TO_STR__(__VA_ARGS__)
#define TO_STR(...) TO_STR_(__VA_ARGS__)

#include <iostream>
int main()
{
    std::cout << "String from #include <string>, ";
    static const char* str = TO_STR(
#include <string>
    );

    std::cout << sizeof(str) / sizeof(char) << " characters:\n\n";
    std::cout << str << "\n";
}

使用 GCC,不会输出任何内容。使用 Visual Studio 2010,#include <string>输出。

如果您可以修改编译链,则可以添加一个预构建步骤,该步骤将包含您想要的文件内容作为字符串(可以使用 CMake 或自定义 makefile 等工具轻松完成)。

于 2012-12-20T11:17:24.627 回答
0

您可以使用 ofstream 打开文件流并读取和输出内容。

于 2012-12-20T10:58:57.300 回答