如何将脚本语言实现到 C 应用程序中?

Posted

技术标签:

【中文标题】如何将脚本语言实现到 C 应用程序中?【英文标题】:How to implement a scripting language into a C application? 【发布时间】:2010-11-12 14:30:27 【问题描述】:

我有一个 C 应用程序,我想包含一种脚本语言来将某些功能放入脚本中。我只是没有这方面的经验,也不知道从哪里开始(仍在学习 C 并试图理解应用程序)。

我的应用程序和脚本之间的嵌入和通信实际上是如何工作的?我想我需要脚本语言的解释器作为库(Windows 上的 .dll 或可以编译到我的应用程序中的 C 源代码)?然后我可以做类似的事情

interpreter->run("myscript", some_object);

脚本如何知道对象的属性?假设我的脚本想要读取或修改 some_object->some_field?

是否有针对这种嵌入进行了优化的脚本语言?我知道有在游戏开发中流行的 Lua,以及像 Python、Perl、php 或 Ruby 这样的语言似乎更有针对性地作为独立应用程序,但我在深层架构方面的知识不允许更多有根据的猜测:) (标记 Lua 和 Python,因为它们是我的最爱,但只要它在 x86 Windows、Linux 和 Mac OS X 上运行,我对其他脚本语言持开放态度,只要它们易于在 C 应用程序中实现)

【问题讨论】:

只是好奇:你能谈谈你的动机吗?您是否为不同的(更好,更简单,...)语法嵌入了另一种语言(因为有可嵌入的解释器完全使用 C 作为他们的语言)?或者它是关于为您的应用程序提供一些可编程接口而无需重新编译?还是为最终用户定制...? 这是一些游戏逻辑,主要是我目前正在计划的角色扮演游戏的对话和任务。 【参考方案1】:

卢阿。它占用空间非常小,速度相当快,而且我(主观上)发现它拥有与 C 交互的最愉快的 API。

如果您想从 C 中接触 Lua 对象 - 使用内置 API 非常容易。如果你想接触 Lua 中的 C 数据 - 这需要更多的工作,通常你需要制作包装方法来公开你想要允许 Lua 修改的内容。

小型代码库和对引入嵌入式解释器的默认库数量的严格控制也意味着您可以对安全性做出合理的假设。

唯一奇怪的部分是基于 1 的数组编号,但是,考虑到迭代器的存在,与我的想法相比,这并没有什么大不了的。

如何与 C 集成:Lua 的分发 tarball 有一个目录“etc”,其中包含一些非常有用的示例,它们应该可以帮助您快速入门。具体来说 - etc/min.c 展示了如何启动解释器,使其解释文件,并使其调用 C 函数(在这种情况下为“打印”)。从那里您可以阅读 Lua 文档和发行版中包含的标准库的源代码。

【讨论】:

我为此使用了 Lua,它非常擅长。它专为嵌入其他系统而设计。当然,同意基于 1 的数组;每种语言都有它的一点点脑损伤,这是 Lua 的一种,但它是可应对的。【参考方案2】:

一些有用的链接:

Embedding Python 嵌入Lua:http://www.lua.org/manual/5.1/manual.html#3,http://www.ibm.com/developerworks/opensource/library/l-embed-lua/index.html Embedding Ruby Embedding PLT Scheme Embedding PERL Embedding TCL Embedding javascript Embedding PHP

我熟悉 Python。 Python 是一种非常丰富的语言,并且有大量可用的库。

【讨论】:

【参考方案3】:

这是来自 Python 网站的用于嵌入 Python 2.6 的文档...

http://docs.python.org/extending/embedding.html

【讨论】:

我发现与 Python 的集成非常易于使用,FWIW。我能够在半天之内构建一些有用且正常运行的东西(包括在我的 C 代码中调用自定义例程)。 我在 C 中嵌入脚本语言的经验仅包括 Perl、Python、Lua 和 Tcl。就学习曲线(从零开始到拥有一个工作程序的时间)而言,我会给 Lua 1,Tcl 2,Python 5,Perl 359,000。但是,在使用 Python 之后,我使用了 Lua 和 Tcl,而我只知道 Perl 学习了 Python 嵌入,所以我的经验可能使 Lua 和 Tcl 看起来都比它们更容易。但我同意 Joe 的看法——用 Python 大约需要半天时间,用 Lua 大约需要 20 分钟。 Lua 很容易嵌入。 我首先接受的是“使用 Lua!”答案是因为我可以用一块石头杀死两只鸟(无论如何我都想学习 Python),而且它确实有效。尊敬的从 Google 提出这个问题的匿名读者:也请阅读所有其他答案,它们都很棒。【参考方案4】:

Lua 完全针对这种嵌入进行了优化。 Roberto Ierusalimschy 的书Lua 编程 是一个很好的起点;你可以得到previous edition free online。

您的脚本如何知道您的 C 对象的属性?

想象一下你的对象是这样定义的:

typedef struct my_object *Object;
Object some_object;

您的 C 代码对该对象的属性了解多少?几乎没有,就是这样。你能做的就是

传递指向对象的指针,将它们放入数据结构等中。

调用真正知道struct my_object 中内容的函数。

Lua 以完全相同的方式访问 C 对象:间接通过函数:

您通过 API 调用将 指针 放在 Lua 堆栈上的对象中,它可以从该对象进入 Lua 数据结构、变量或 Lua 世界中的任何其他位置。 p>

您定义了解对象内部的函数,然后将这些函数导出到 Lua。

“辅助库”中有很多东西可以帮助您。不要忽视它!

所有这一切都在罗伯托的书的第三部分中得到了清晰的解释,其中包括一些例子。一点是

您可以选择自己分配内存(“轻量级用户数据”)或让 Lua 分配内存。通常最好让 Lua 分配内存,因为它可以在不再需要时自动释放对象,并且您还可以关联一个 Lua metatable,它允许您(以及其他技巧)允许对象参与标准 Lua 操作,例如查找字段,而不仅仅是函数调用。

最后一点:虽然可以使用 SWIG 或 toLua 或其他工具来尝试生成连接 C 和 Lua 的代码,但我强烈建议您自己手动编写代码。这实际上很容易做到,而且是了解实际情况的唯一方法。

【讨论】:

【参考方案5】:

Lua 正是为此目的而设计的,而且相当容易使用。

另一个值得关注的是QtScript,它是基于 Javascript 的,尽管这需要一些工作来“qt-ify”你的应用程序。

【讨论】:

【参考方案6】:

您可能还想看看SWIG,简化的包装器和接口生成器。正如人们猜想的那样,它会生成大量样板代码来将您的 C/C++ 代码连接到脚本引擎(手动执行这可能非常麻烦)。

它支持 Python 和 Lua(您的偏好)和许多其他语言。生成扩展脚本语言的模块非常容易。扩展嵌入,这是您想要的,需要更多的努力。

【讨论】:

【参考方案7】:

你可以看看Game Scripting Mastery。由于我对计算机游戏的高级方面也很感兴趣,所以经常向我推荐这本书。

不幸的是,这本书似乎已经绝版(至少在欧洲)。

【讨论】:

【参考方案8】:

大多数脚本语言都允许嵌入到 C 中,并且通常允许您将 C 代码中的某些对象甚至函数公开给脚本,以便它可以操作对象并调用函数。

正如 Lua 是为此目的而设计的嵌入,使用解释器,您可以将对象暴露给脚本并从 C 调用 lua 函数,搜索 embedding lua in C,您应该会找到很多信息,也不要错过lua手册部分"The Application Programming Interface"

虽然 Python 更适合独立使用,但它也可以嵌入,如果您的脚本使用 Python 提供的大量库,它会很有用。

【讨论】:

以上是关于如何将脚本语言实现到 C 应用程序中?的主要内容,如果未能解决你的问题,请参考以下文章

Lua脚本语言快速入门手册

如何将脚本实现到 LibGDX 中?

从游戏脚本语言说起,剖析Mono所搭建的脚本基础

如何使用TCL脚本在嵌入式系统上测试C语言功能?

Java中使用Lua脚本语言(转)

Python语言--Crontab结合Python脚本实现将日志每天写入到文件中