C++ 从文本文件执行代码
C++ executing a code from a text file
标题说明了一切。像编译器但不一样。我希望从 C++ 中的外部源执行代码的特定部分。我不知道这是否可能,因为它在 Javascript、Python 等
中
假设我有一个标题为 sample.txt 的文本文件,如下所示:
int a = 10, c;
cin >> c;
cout << a + c;
然后我会在 main() 函数中调用文本文件并编译 .exe 文件。当我 运行 它时,它是否有可能动态地表现得好像文件中的代码嵌入其中并写入 10 + 输入?应更改源文件,下次 运行s 时将应用不同的结果。顺便说一句,这只是一段代码示例,我可能想要 运行 一些 for/while 循环和 if 条件等
PS:我知道如何从文件中读取并将其分配为整数或将其写入屏幕,这不是我想要的。我需要编译通过的函数。谢谢
有几种方法可以解决这个问题。
fork 一个命令行编译器和 fork 到 运行 结果,通过 STDIN/STDOUT
传递输入和输出
(虽然我知道你是从 C++ 调用程序中要求这个的,但为了简单起见,我在 bash 中演示了这个想法。)
文件:run_it.sh
:
#!/bin/bash
set -e # Bail on the first error
FN_IN=./sample.txt
FN_WRAPPED=./wrapped.cc
FN_EXE=./wrapped
CC=g++
# Wrap the fragment in a full C++ program and compile it.
function build_wrapper () {
cat > $FN_WRAPPED <<'EOF'
#include <iostream>
using namespace std;
int main(int argc, char **argv) {
EOF
cat $FN_IN >> $FN_WRAPPED
cat >> $FN_WRAPPED <<'EOF'
return 0;
}
EOF
$CC -o $FN_EXE $FN_WRAPPED
}
# Run the wrapper, passing input through STDIN and reading the output from STDOUT.
function run () {
local IN=
echo $IN | $FN_EXE
}
# Remove the wrapper (both code and compiled).
function clean_up () {
rm -f $FN_WRAPPED $FN_EXE
}
build_wrapper
IN=24
OUT=$(echo "$IN" | $FN_EXE)
echo "Result = $OUT"
echo "Another result = $(run 16)"
clean_up
$ ./run_it.sh
Result = 34
Another result = 26
使用类似 LLVM 的东西在进程中编译函数并调用它
这种方法非常强大,但也有些复杂。
简而言之,您想要
- 将
sample.txt
读入内存。
- 将其编译为一个函数。
- 调用函数。
一些可能有用的链接:
编译后的 C++ 程序只包含执行编译后的源代码所必需的机器指令,语言标准没有指定任何机制让用户在 运行 时生成额外的机器指令。
为了提供脚本功能 - 生成程序流以响应输入文本解析的能力 - 您必须提供解析器和执行引擎。
int main()
{
std::string cmd;
int op1, op2;
while (cin >> cmd >> op1 >> op2) {
if (cmd == "add")
std::cout << op1 + op2 << "\n";
else if (cmd == "sub")
std::cout << op1 - op2 << "\n";
else
std::cerr << "error\n";
}
}
许多解释型语言最初是用 C 或 C++ 编写的,因此通常可以将它们构建为一个库,然后您可以将其合并到应用程序中,以便程序可以调用它们以提供嵌入式脚本语言。此类语言的常见示例是 Lua, Python and JavaScript。然后您的程序可以将要执行的代码传递给解释器。
编写自己的 lua 解释器可能如下所示:
#include <iostream>
#include <string>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
bool get_input(std::string& in)
{
bool result;
do {
std::cout << "lua> " << std::flush;
result = std::getline(std::cin, in);
} while (result && in.empty());
return result;
}
int main (void) {
lua_State *L = lua_open(); // open lua
luaL_openlibs(L); // open standard libraries
std::string in;
while (get_input(in)) {
if (in.empty())
continue;
int error = luaL_loadbuffer(L, in.c_str(), in.size(), "line") ||
lua_pcall(L, 0, 0, 0);
if (error) {
std::cerr << lua_tostring(L, -1) << '\n';
lua_pop(L, 1); // remove the error message from the stack
}
}
lua_close(L);
}
在linux之下:
$ g++ -Wall -O3 -o mylua mylua.cpp -I/usr/include/lua5.1 -llua
$ ./mylua
lua> print("hello")
hello
lua> error
[string "line"]:1: '=' expected near '<eof>'
lua>
标题说明了一切。像编译器但不一样。我希望从 C++ 中的外部源执行代码的特定部分。我不知道这是否可能,因为它在 Javascript、Python 等
中假设我有一个标题为 sample.txt 的文本文件,如下所示:
int a = 10, c;
cin >> c;
cout << a + c;
然后我会在 main() 函数中调用文本文件并编译 .exe 文件。当我 运行 它时,它是否有可能动态地表现得好像文件中的代码嵌入其中并写入 10 + 输入?应更改源文件,下次 运行s 时将应用不同的结果。顺便说一句,这只是一段代码示例,我可能想要 运行 一些 for/while 循环和 if 条件等
PS:我知道如何从文件中读取并将其分配为整数或将其写入屏幕,这不是我想要的。我需要编译通过的函数。谢谢
有几种方法可以解决这个问题。
fork 一个命令行编译器和 fork 到 运行 结果,通过 STDIN/STDOUT
传递输入和输出(虽然我知道你是从 C++ 调用程序中要求这个的,但为了简单起见,我在 bash 中演示了这个想法。)
文件:run_it.sh
:
#!/bin/bash
set -e # Bail on the first error
FN_IN=./sample.txt
FN_WRAPPED=./wrapped.cc
FN_EXE=./wrapped
CC=g++
# Wrap the fragment in a full C++ program and compile it.
function build_wrapper () {
cat > $FN_WRAPPED <<'EOF'
#include <iostream>
using namespace std;
int main(int argc, char **argv) {
EOF
cat $FN_IN >> $FN_WRAPPED
cat >> $FN_WRAPPED <<'EOF'
return 0;
}
EOF
$CC -o $FN_EXE $FN_WRAPPED
}
# Run the wrapper, passing input through STDIN and reading the output from STDOUT.
function run () {
local IN=
echo $IN | $FN_EXE
}
# Remove the wrapper (both code and compiled).
function clean_up () {
rm -f $FN_WRAPPED $FN_EXE
}
build_wrapper
IN=24
OUT=$(echo "$IN" | $FN_EXE)
echo "Result = $OUT"
echo "Another result = $(run 16)"
clean_up
$ ./run_it.sh
Result = 34
Another result = 26
使用类似 LLVM 的东西在进程中编译函数并调用它
这种方法非常强大,但也有些复杂。
简而言之,您想要
- 将
sample.txt
读入内存。 - 将其编译为一个函数。
- 调用函数。
一些可能有用的链接:
编译后的 C++ 程序只包含执行编译后的源代码所必需的机器指令,语言标准没有指定任何机制让用户在 运行 时生成额外的机器指令。
为了提供脚本功能 - 生成程序流以响应输入文本解析的能力 - 您必须提供解析器和执行引擎。
int main()
{
std::string cmd;
int op1, op2;
while (cin >> cmd >> op1 >> op2) {
if (cmd == "add")
std::cout << op1 + op2 << "\n";
else if (cmd == "sub")
std::cout << op1 - op2 << "\n";
else
std::cerr << "error\n";
}
}
许多解释型语言最初是用 C 或 C++ 编写的,因此通常可以将它们构建为一个库,然后您可以将其合并到应用程序中,以便程序可以调用它们以提供嵌入式脚本语言。此类语言的常见示例是 Lua, Python and JavaScript。然后您的程序可以将要执行的代码传递给解释器。
编写自己的 lua 解释器可能如下所示:
#include <iostream>
#include <string>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
bool get_input(std::string& in)
{
bool result;
do {
std::cout << "lua> " << std::flush;
result = std::getline(std::cin, in);
} while (result && in.empty());
return result;
}
int main (void) {
lua_State *L = lua_open(); // open lua
luaL_openlibs(L); // open standard libraries
std::string in;
while (get_input(in)) {
if (in.empty())
continue;
int error = luaL_loadbuffer(L, in.c_str(), in.size(), "line") ||
lua_pcall(L, 0, 0, 0);
if (error) {
std::cerr << lua_tostring(L, -1) << '\n';
lua_pop(L, 1); // remove the error message from the stack
}
}
lua_close(L);
}
在linux之下:
$ g++ -Wall -O3 -o mylua mylua.cpp -I/usr/include/lua5.1 -llua
$ ./mylua
lua> print("hello")
hello
lua> error
[string "line"]:1: '=' expected near '<eof>'
lua>