问题 有没有办法在C ++中从字符串转换为纯代码?


我知道可以从.txt文件中读取然后将其中的各个部分转换为字符串,字符和整数值,但是是否可以获取字符串并将其用作程序中的实际代码?


码:

string codeblock1="cout<<This is a test;";
string codeblock2="int array[5]={0,6,6,3,5};}";
int i;
cin>>i;
if(i)
{
execute(codeblock1);
}
else
{
execute(codeblock2);
}

哪里 execute 是一个从文本转换为实际代码的函数(我不知道是否实际上有一个名为execute的函数,我正在使用它来实现我的例子)。


7393
2018-05-05 03:37


起源

出于同样的原因,你不允许直接使用表单输入(在Web上)(即SQL注入),这并不是我最安全的事情。 - Dan Fego
我只是想知道它是否可能。
嗯,你看它被称为编译器。它接收一个文本文件并生成实际代码。 - Brian Gianforcaro
我不明白为什么这样的问题会被低估。不 您 一个新手? SO只是经验丰富的专业人士之间高层次复杂讨论的地方,不受初级开发人员欢迎吗? - Eli Bendersky
为什么要投票? - Paulo


答案:


您可以创建一个函数并解析您喜欢的任何字符串并从中创建数据结构。这称为解析树。随后,您可以检查解析树并生成必要的动态结构以执行逻辑运算。随后将解析树转换为执行的运行时表示。

所有编译器都是这样做的。他们接受您的代码并根据此生成机器代码。在您的特定情况下,您希望语言为自己编写代码。通常,这是在代码生成器的上下文中完成的,它是更大的构建过程的一部分。如果您编写一个程序来解析您的语言(考虑使用flex和bison进行此操作)生成代码,您可以获得所需的结果。


3
2018-05-05 03:41





在C ++中,没有简单的方法可以做到这一点。此功能适用于更高级别的语言,如Python,Lisp,Ruby和Perl(通常有一些变体 eval 功能)。但是,即使在这些语言中,这种做法也是不受欢迎的,因为它会导致代码非常难以理解。

重要的是你问自己(也许告诉我们)你为什么要这样做?

或者你只是想知道它是否可能?如果是这样的话,那就是毛茸茸的。你可以编写一个C ++源文件(生成你想要的任何内容,只要它是有效的C ++),然后编译它并链接到你的代码。当然,只要编译器在运行时可用(并且您只需执行它),所有这一切都可以自动完成 system)。我知道有人曾经做过一次重大优化。它不漂亮,但可以使用。


8
2018-05-05 03:46





许多脚本语言提供了这种功能,一直回到过去 eval 在LISP中 - 但C和C ++不会在运行时公开编译器。

规范中没有任何内容阻止您创建和执行某些任意机器语言,如下所示:

char code[] = { 0x2f, 0x3c, 0x17, 0x43 }; // some machine code of some sort
typedef void (FuncType*)();               // define a function pointer type
FuncType func = (FuncType)code;           // take the address of the code
func();                                   // and jump to it!

但出于安全考虑,如果您尝试这样做,大多数环境都会崩溃。 (许多病毒通过说服普通程序来做这样的事情来工作。)

在正常环境中,您可以做的一件事是创建一个完整的程序作为文本,然后调用编译器来编译它并调用生成的可执行文件。

如果您想在自己的内存空间中运行代码,可以调用编译器来构建DLL(或.so,具体取决于您的平台),然后链接DLL并跳转到它。


3
2018-05-05 03:50



实际上很多平台 惯于 如果你这样做会崩溃;曾经有一个名为SoftWire的项目就是这样做的(如果我没记错的话,它可以让你在C中为软件渲染器写'像素着色器')。在作为玩具编程语言的JIT编译器消失之后,我最终重写了该项目的一个克隆。这很有趣,但很危险......做吧! - Zach Snow
是的,它运行的平台很多,但遗憾的是操作系统和硬件设计人员似乎趋向于锁定“不可执行”数据。我知道一些PS2游戏用这种技术做了真正疯狂和奇妙的事情......很高兴,PS3 SPU中存在“代码就是数据代码”,它根本就没有内存保护! - Charlie


首先,我想说,我从来没有实现过类似的东西,但我可能会离开,但是,你试过了吗? CodeDomProvider上课 System.CodeDom.Compiler 命名空间?我感觉上课了 System.CodeDom 可以为您提供您正在寻找的功能。

当然,它都是.NET代码,而不是任何其他平台

这里是样品


1
2018-05-05 04:04





是的,你只需要构建一个编译器(可能还有一个链接器)就可以了。

可以将诸如Python之类的几种语言嵌入到C / C ++中,这可能是一种选择。


0
2018-05-05 03:43





这有点可能,但不仅仅是直接的C / C ++。你需要一些底层,比如LLVM。

查看 C-REPL 和 CCONS


0
2018-05-05 03:44





你可以做到这一点的一种方法是 提升Python。此时您不会使用C ++,但它是允许用户使用脚本语言与现有程序交互的好方法。我知道这不是你想要的,但也许它可能有所帮助。


0
2018-05-05 03:44





听起来你正在尝试创建“C ++脚本”,据我所知,它并不存在。 C ++是一个 编译语言。这意味着它必须在执行之前始终编译为本机字节码。您可以将代码作为函数包装,通过编译器运行,然后动态执行生成的DLL,但是您不会访问编译的DLL通常不会获得的任何内容。

您最好尝试在Java,JavaScript,VBScript或.NET中执行此操作,这些都处于一个阶段或另一个阶段 解释语言。大多数这些语言都有 eval 要么 execute 功能就是这个,或者可以只是 included作为文本。

当然,执行代码块并不是最安全的想法 - 它会让您容易受到各种数据执行攻击。

我的建议是创建一个服务于您的应用程序的脚本语言。出于安全原因,这将为用户提供有限的指令集,并允许您比编译的外部块更加动态地与现有程序交互。


0
2018-05-05 03:49



C ++规范中绝对没有需要编译的东西。它被设计成一种编译语言,并且(据我所知)始终如此实现。类似地,即使目标平台是预先指定的,Java也是与C ++一样的编译语言。更不用说编译与解释并不意味着没有或有某种eval:Common Lisp通常是带有(eval ...)的编译语言,而我没有使用解释语言。 - David Thornley