是否可以拥有这样的功能:
const char* load(const char* filename_){
return
#include filename_
;
};
所以你不必硬编码#include文件?
也许有一些宏?
我画了一个空白,伙计们。我无法判断它是否无法实现,或者它是否只是一个奇怪的解决方案。
编辑:
另外,理想的做法是将其作为编译时操作,否则我知道有更标准的方法来读取文件。因此首先考虑#include。
答案 0 :(得分:1)
这绝对不可能。
原因是 - 正如贾斯汀在评论中所说的那样 - #include
在编译时进行评估。
要在运行时包含文件,需要在程序中“完成”编译器。很多脚本语言都支持这样的东西,但C ++是一种编译语言,它的工作方式不同:编译和运行时间是严格分开的。
答案 1 :(得分:1)
我无法判断它是不是很可能
我可以。这是不可能的。
filename_
字符串的内容直到运行时才确定 - 运行预处理器时内容未知。编译前处理预处理器宏(或根据您的观点编译第一步)。
如果在运行时确定文件名的选择,则还必须在运行时读取该文件(例如使用fstream
)。
另外,理想的做法是将其作为编译时操作
您可以影响所包含文件选择的最新时间是预处理器运行时。可用于影响文件的是预处理器宏:
#define filename_ "path/to/file"
// ...
return
#include filename_
;
答案 2 :(得分:1)
您不能使用#include
做您想做的事。
实现这种功能的C ++方式是:
最好将返回类型更改为std::string
,以减轻处理动态分配内存的负担。
std::string load(const char* filename)
{
std::string contents;
// Open the file
std::ifstream in(filename);
// If there is a problem in opening the file, deal with it.
if ( !in )
{
// Problem. Figure out what to do with it.
}
// Move to the end of the file.
in.seekg(0, std::ifstream::end);
auto size = in.tellg();
// Allocate memory for the contents.
// Add an additional character for the terminating null character.
contents.resize(size+1);
// Rewind the file.
in.seekg(0);
// Read the contents
auto n = in.read(contents.data(), size);
if ( n != size )
{
// Problem. Figure out what to do with it.
}
contents[size] = '\0';
return contents;
};
<强> PS 强>
仅当您因某种原因需要将返回对象的内容视为空终止字符串时,才需要在返回的对象中使用终止空字符。否则,它可能会被省略。
答案 3 :(得分:1)
实际上,您要求使用C ++编写PHP构造。这可以做到,因为太多事情可以,但你需要一些尴尬的先决条件。
编译器必须链接到您的可执行文件中。因为您调用的操作&#34; hardcoding&#34;对于要执行的代码至关重要。
a(可能非常繁琐)链接器再次进入您的可执行文件,合并新代码并解决任何函数调用等双向。
此外,新导入的代码不可以被的其余部分访问,而没有编写(当然也没有编译!),并记住了这些信息。所以你需要一个切入点和一种交换信息的方法。然后在这个信息块中,您甚至可以将指针指向要调用的代码。
并非所有架构和操作系统都支持此,因为&#34;数据&#34;和#34;代码&#34;两个问题最好分开。守则可能有害;把它想象成硝酸。外部数据是流动和光滑的,如甘油。正如我所说,处理硝酸甘油是可能的。实用和安全是完全不同的。
满足先决条件后,您将拥有两个或三个不错的额外功能,并且可以写:
void *load(const char* filename, void *data) {
// some "don't load twice" functionality is probably needed
void *code = compile_source(filename);
if (NULL == code) {
// a get_last_compiler_error() would be useful
return NULL;
}
if (EXIT_SUCCESS != invoke_code(code, data)) {
// a get_last_runtime_error() would also be useful
release_code(code);
return NULL;
}
// it is now the caller's responsibility to release the code.
return code;
}
当然这将是一场安全噩梦,其中包含源代码并被导入到正在运行的应用程序中。
维护代码将是一个不同但同样可怕的噩梦,因为您需要两个工具链 - 一个用于构建可执行文件,一个嵌入在所述可执行文件中 - 并且他们不会&# 39;必须自动兼容。你会大声哭泣,因为这个领域的所有错误都要来欢欣鼓舞。
在C ++中实现require_once
可能很有趣,但you thought it could answer a problem you have。 它究竟是什么?也许它可以用更多的C ++方式解决。
更好的替代方案,也考虑到性能等,预先编译可加载模块,并在运行时加载它。
如果需要对可执行文件执行小调整,请将参数放入外部配置文件并提供重新加载它的机制。一旦模块符合固定规范,您甚至可以提供&#34;插件&#34;首次开发可执行文件时无法使用。