将脚本预编译为 C++ 应用程序中的对象

Precompile script into objects inside C++ application

我需要为我的用户提供将数学计算写入程序的能力。我计划有一个简单的文本界面,其中包含一些按钮,包括用于验证脚本语法、保存等的按钮。

这里是有趣的地方。用户正在编写的这些功能需要在通信应用程序中以数兆字节的线路速度执行。所以我需要编译语言的速度,但需要脚本的使用。一种完全解释的语言是行不通的。

我的想法是在 C++ 应用程序初始化时将保存的用户模块预编译为对象。然后我可以使用这些对象在调用时执行代码。以下是我想到的工作流程:

1)脚本测试(初写):在编辑器中编写代码,保存,编译成对象(测试语法),运行 with test I/O,Edit Code

2)代码的使用(应用程序的正常运行):从文件加载脚本,将脚本编译成对象,运行目标代码,运行目标代码,运行目标代码等

我查看了几个现成的口译员,但找不到我要找的东西。我考虑过 JAVA,因为它非常快,但我需要加载 JAVA 虚拟机,这意味着在 C 和虚拟机之间传递对象......接口是这里的瓶颈。如果可能的话,我真的需要创建一个本地 C++ 对象 运行ning C++ 代码。我还需要能够以受控方式有效地 运行 多个处理器上的代码。

我不是在寻找有关如何完成此操作的完整解释,因为我可以自己进行研究。然而,我现在已经在这里停滞了几天,我真的需要一个地方开始寻找。

作为最后的手段,我将创建我自己的脚本语言来满足需要,但是对于所有优秀的解释器来说这似乎是一种浪费。我还考虑过采用现有的开源编译器并将其切片以获得我需要的功能......只是不将编译结果保存到磁盘......我不知道。如果可能的话,我更愿意使用主线语言...但这不是必需的。

如有任何帮助,我们将不胜感激。我知道这不是你的 运行 我在这里的工厂想法,但必须有人以前做过。

谢谢!

P.S。 我在写这篇文章时突然想到的一个想法是:使用真正的 C 编译器创建目标代码,将其作为 dll 库保存到磁盘,然后重新加载并 运行 它在 "my" 代码中怎么样? ?你能用 MS Visual Studio 做到这一点吗?我需要查看编译器的许可...如何在主应用程序继续 运行 时动态重新加载库...嗯,然后我可以将用户创建的 "functions" 分组到图书馆团体。好的,这个特别的大脑垃圾就够了...

一个可能的解决方案是使用 gcc(MingW,因为您使用的是 windows)并从您的用户定义代码构建一个 DLL。 DLL 应该只导出一个函数。您可以使用 win32 API 来处理 DLL(LoadLibrary/GetProcAddress 等)。在这项工作结束时,您将获得一个 C 风格的函数指针。现在的问题是争论。如果您的计算只有一个参数,您可以强制转换为 double (*funct)(double),但如果您有许多参数,则需要匹配它们。

我想我找到了一种使用标准 C 来完成此操作的方法。

1) 需要使用标准C,因为当它被编译成dll时,生成的接口与多个编译器交叉兼容。我计划使用 MS Visual Studio 进行初级开发,并使用 gcc(windows 版本)

在我的应用程序中编译对象

2) 我将向用户公开某些变量(输入和输出)并跨单元标准化它们。这允许使用相同的界面开发多个单元。

3) 用户只会使用标准的C 句法和文法来创建函数内部。然后我将用文本包装该函数以完全定义该函数及其环境(还记得我打算公开的那些变量吗?)我还可以使用名称参数将多个函数分组在一个可执行单元 (dll) 下。

4) 当用户希望测试他们的功能时,我从内存中转储 dll,在 gcc 中用我的包装器编译他们的代码,然后将 dll 重新加载到内存中并 运行 它。我会让他们定义用于测试的输入和输出。

5) test/create 步骤完成后,我创建了一个编译库,可以在 运行 时间加载并通过指针处理。输入和输出将被标准化,所以我总是知道我的 I/O 是什么。

6) 标准化 I/O 的唯一问题是一些输入和输出可能不会被使用。我需要看看我是否可以输入默认值或其他东西。

所以,总结一下:

想象一个带有文本框和几个按钮的应用程序。您被告知您的输入名为 A、B 和 C,您的输出为指定类型的 X、Y 和 Z。然后使用标准 C 代码和指定库中的函数编写一个函数(我在想数学等)

现在你已经完成了...你会在下面看到几个框来定义你的输入。您填写它们并点击测试按钮。这会将您的代码包装在函数上下文中,从内存中转储现有的 dll(如果存在)并将您的代码与同一组中的任何其他函数一起编译(您可以定义的另一个参数,基本上只是用户的名称。)然后它 运行 使用函数指针,使用 UI 中定义的输入来调用函数。输出被发送给用户,这样他们就可以确定他们的功能是否有效。如果有任何编译错误,也会输出给用户。

现在是 运行 真正的时候了。当然,我一直在跟踪哪些函数在哪里,所以我动态打开 dll,并使用函数指针将所有函数加载到内存中。我开始将数据推到一侧,函数给出了我需要的答案。跟踪 I/O 并确保以正确的顺序调用函数会有一些开销,但执行将以编译后的机器代码速度......这是我的主要要求。

现在...我已经用两种不同的方式解释了我认为可行的方法。你能想出任何可以阻止它工作的东西,或者任何 advice/gotchas/lessons 学到的可以帮助我的东西吗?从接口类型到以这种方式动态加载 dll 的提示,再到以这种方式使用 gcc 编译器……等等,这些都是最有帮助的。

谢谢!