【问题标题】:Is there a way to convert from a string to pure code in C++?有没有办法在 C++ 中将字符串转换为纯代码?
【发布时间】:2009-05-05 03:37:09
【问题描述】:

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


代码:

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 的函数,我将它用于我的示例)。

【问题讨论】:

  • 出于同样的原因,您不允许直接使用表单输入(在 Web 上)(即 SQL 注入),这对我来说并不是最安全的做法。跨度>
  • 我只是想知道这是否可能。
  • 嗯,你看它叫做编译器。它接受一个文本文件并生成真实的代码。
  • 我不明白为什么这样的问题会被否决。 不是曾经的新手吗? SO 是否只是经验丰富的专业人士之间进行高级复杂讨论的场所,不欢迎初级开发人员?

标签: text


【解决方案1】:

在 C++ 中,没有简单的方法可以做到这一点。此功能在 Python、Lisp、Ruby 和 Perl 等高级语言中可用(通常带有 eval 函数的一些变体)。然而,即使在这些语言中,这种做法也是不受欢迎的,因为它会导致代码非常不可读。

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      许多脚本语言都提供这种功能,在 LISP 中一直可以追溯到 eval - 但 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 并跳转到它。

      【讨论】:

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

      首先,我想说的是,我自己从未实现过类似的东西,而且我可能还差得很远,但是,您是否尝试过 System.CodeDom.Compiler 命名空间中的 CodeDomProvider 类?我感觉System.CodeDom 中的类可以为您提供您正在寻找的功能。

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

      here for sample

      【讨论】:

        【解决方案5】:

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

        可以将 Python 等多种语言嵌入到 C/C++ 中,这可能是一种选择。

        【讨论】:

          【解决方案6】:

          这有点可能,但不是直接使用 C/C++。您将需要下面的一些层,例如 LLVM。

          查看c-replccons

          【讨论】:

            【解决方案7】:

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

            【讨论】:

              【解决方案8】:

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

              您最好尝试在 Java、JavaScript、VBScript 或 .NET 中执行此操作,它们处于某个阶段或另一种解释语言。这些语言中的大多数要么为此具有 evalexecute 函数,要么只是 included 作为文本。

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

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

              【讨论】:

              • C++ 规范中绝对没有需要编译的内容。它被设计成一种编译语言,并且(据我所知)总是这样实现的。类似地,Java 与 C++ 一样是一种编译语言,即使目标平台是预先指定的。更不用说编译与解释并不意味着没有或没有某种 eval:Common Lisp 通常是带有 (eval ...) 的编译语言,而我使用没有的解释语言。
              【解决方案9】:

              不容易,因为 C++ 是一种编译语言。有几个人指出了让它工作的迂回方法——要么执行编译器,要么将编译器或解释器合并到你的程序中。如果你想走解释器路线,你可以通过使用现有的开源项目为自己节省很多工作,例如Lua

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-02-24
                • 2023-01-30
                • 2022-11-24
                • 2023-01-27
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多