热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c/c++开发分享脚本引擎–调用“未知”function

我想创建脚本引擎,我发现了奇怪的问题。首先我解释一下它将如何工作:脚本引擎(DLL)将独立于将要使用的应用程序。SE将导出两个函数(有些类似,它可能有点不同):Thiswillbe

我想创建脚本引擎,我发现了奇怪的问题。 首先我解释一下它将如何工作:脚本引擎(DLL)将独立于将要使用的应用程序。 SE将导出两个函数(有些类似,它可能有点不同):

// This will be called on beginning of host program, register set of functions, that // script will provide to usere SetFunc(void *func,byte code,char *descript); func : pointer to existing function from host application (eg printf) code : code for script compiler descript : func description, if eventually needed // function calling functions inc Script Engine (in compiled DLL, which can't be // modified for host application, only input for SE is SetFunc CallFunc(void *instr); instr : pointer to memory block, in which is stored (instr_code - byte)(void* - pointer to func)(params_len - unsigned int)(params - data block) /--- this will be filled after loading script to SE, according to table of registred functions (via Setfunc). Callfunc(void *func,void *params,unsigned int param_length); func : pointer to function params : parameters for function in memory block (extracted from instr) param_length : what to say :o) 

主程序示例:

 #include "ScriptEngine.h" // this will create connection to SE DLL float add(double num1,double num2) { return (num1+num2); } int main() { SetFunc(add,1,"f:d,d/2"); // register one function to SE LoadScript("simple.sc","simple"); // load script to memory ExecuteScript("simple"); // execute script (only add two nums) } 

和脚本:

 main() { add(3.45,8.87); } // after some compilation to binary format : ... (1)(NULL)(16)(3.45)(8.87) (instruction for "system call" (registred via SetFunc) ... // after LoadScript (1)(0x00402cc)(16)(3.45)(8.87) 

并且在ExecuteScript上调用内部DLL函数CallFunc,并从instr输入设置参数。

如何从指针调用函数并在此环境中设置参数? 我可以通过这种方式创建这个,或者有人有另外的想法,如何做到这一点?

感谢所有答案:o)

    一种不同的,更简单的方法:将脚本编译为基于堆栈的虚拟机的指令。 应该要求所有本机函数遵循统一签名,以便我们可以使用单个函数指针typedef来调用它们。 例如,以下是我们如何实现并向脚本引擎公开add函数:

     // Common type for all native functions. typedef void(*NativeFuncPtr)(VM*); // The Virtual Machine is wrapped in a `VM` object. // popDouble() and pushDouble() make use of the more primitive // stack operations push() and pop(). void add(Vm* vm) { double a = vm->popDouble(); double b = vm->popDouble(); vm->pushDouble(a + b); // leave the result on the VM stack. } // The call to setFunc will map the string "add" to the address of the // `add()` function in a hashtable. vm->setFunc("add", &add); 

    现在让我们看一下编译add(3.45,8.87);可能方法add(3.45,8.87); 到VM字节码:

     pushDouble 8.87 pushDouble 3.45 call add 

    这是VM执行这些指令的方式:

    VM在本机函数表中找到“add”并调用它:

     NativeFuncPtr fptr = nativeFunctions["add"]; (*fptr)(this); 

    一旦函数完成执行,VM将在数据堆栈上得到结果 – 12.32

    这是一个非常简单的解释。 在实际实现中,数据栈可能只能保存机器字大小的整数。 所以它实际上将包含double值的地址。 像popDouble这样的popDouble应该隐藏本机函数实现者的这些细节。

      以上就是c/c++开发分享脚本引擎 – 调用“未知”function相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注(编程笔记)。


      推荐阅读
      • 本文整理了一份基础的嵌入式Linux工程师笔试题,涵盖填空题、编程题和简答题,旨在帮助考生更好地准备考试。 ... [详细]
      • 在Qt框架中,信号与槽机制是一种独特的组件间通信方式。本文探讨了这一机制相较于传统的C风格回调函数所具有的优势,并分析了其潜在的不足之处。 ... [详细]
      • 本文介绍了一种方法,通过使用Python的ctypes库来调用C++代码。具体实例为实现一个简单的加法器,并详细说明了从编写C++代码到编译及最终在Python中调用的全过程。 ... [详细]
      • 本文详细介绍了在Luat OS中如何实现C与Lua的混合编程,包括在C环境中运行Lua脚本、封装可被Lua调用的C语言库,以及C与Lua之间的数据交互方法。 ... [详细]
      • 想把一组chara[4096]的数组拷贝到shortb[6][256]中,尝试过用循环移位的方式,还用中间变量shortc[2048]的方式。得出的结论:1.移位方式效率最低2. ... [详细]
      • 本文详细介绍了Linux系统中信号量的相关函数,包括sem_init、sem_wait、sem_post和sem_destroy,解释了它们的功能和使用方法,并提供了示例代码。 ... [详细]
      • Windows Phone 弹出窗口实现方案
        在当前版本的 Silverlight for Windows Phone 中,由于缺乏对 ChildWindow 的支持,开发者需要采用其他方法来实现弹出窗口的功能。本文将探讨几种有效的解决方案。 ... [详细]
      • 本文介绍了如何通过C#语言调用动态链接库(DLL)中的函数来实现IC卡的基本操作,包括初始化设备、设置密码模式、获取设备状态等,并详细展示了将TextBox中的数据写入IC卡的具体实现方法。 ... [详细]
      • 如何从BAM文件绘制ATAC-seq插入片段长度分布图?
        在ATAC-seq数据处理中,插入片段长度的分布图是一个重要的质量控制指标,它能反映出核小体的周期性排列。本文将详细介绍如何从BAM文件中提取并绘制这些数据。 ... [详细]
      • 本文详细介绍了如何利用 Bootstrap Table 实现数据展示与操作,包括数据加载、表格配置及前后端交互等关键步骤。 ... [详细]
      • HTML:  将文件拖拽到此区域 ... [详细]
      • 深入理解Java SE 8新特性:Lambda表达式与函数式编程
        本文作为‘Java SE 8新特性概览’系列的一部分,将详细探讨Lambda表达式。通过多种示例,我们将展示Lambda表达式的不同应用场景,并解释编译器如何处理这些表达式。 ... [详细]
      • 本文介绍了如何利用X_CORBA实现远程对象调用,并通过多个示例程序展示了其功能与应用,包括基础的Hello World示例、文件传输工具以及一个完整的聊天系统。 ... [详细]
      • C#中使用Dotfuscator Pro进行代码混淆
        由于Visual Studio自带的混淆工具功能有限,本文将介绍如何使用Dotfuscator Pro进行更高级的代码混淆。包括设置字符串加密、添加可执行文件和动态链接库、调整混淆选项等步骤。 ... [详细]
      • WPF项目学习.一
        WPF项目搭建版权声明:本文为博主初学经验,未经博主允许不得转载。一、前言记录在学习与制作WPF过程中遇到的解决方案。使用MVVM的优点是数据和视图分离,双向绑定,低耦合,可重用行 ... [详细]
      author-avatar
      难得有人待我好_212
      这个家伙很懒,什么也没留下!
      PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
      Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有