Chinaunix首页 | 论坛 | 博客
  • 博客访问: 233237
  • 博文数量: 56
  • 博客积分: 2480
  • 博客等级: 大尉
  • 技术积分: 475
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-28 10:57
文章分类

全部博文(56)

文章存档

2012年(36)

2011年(4)

2010年(2)

2009年(14)

我的朋友

分类: C/C++

2012-04-26 11:54:41

函数是 script 中的一等公民。

在 C++ 中调用 script 中的函数练习一
  • script 定义一个匿名的对象,其func属性是一个函数。

在C++代码中:

  • evaluate() 的结果是该对象
  • 取其 func 属性
  • 调用该函数

这儿涉及的始终是 QScriptValue !

#include /QCoreApplication>
#include /QDebug>
#include

const char script[]="({\n"
" func: function(x){return x*100}\n"
"})\n";

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QScriptEngine engine;
QScriptValue object = engine.evaluate(script);
QScriptValue func = object.property("func");
QScriptValue res = func.call(object, QScriptValueList()<<10);
if (engine.hasUncaughtException()){
qDebug()<<engine.uncaughtException().toString();
qDebug()<<engine.uncaughtExceptionBacktrace().join("\n");
} else {
qDebug()<<res.toNumber();
}
return a.exec();
}
练习二
  • script 中定义一个全局函数

C++ 代码中:

  • evaluate() 该脚本
  • 通过 engine.globalObject() 的属性获得该函数
  • 调用函数(传递给对象的是一个无效的 QScriptValue())

#include /QCoreApplication>
#include /QDebug>
#include

const char script[]="function func(x){return x*100}\n";

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QScriptEngine engine;
engine.evaluate(script);
QScriptValue func = engine.globalObject().property("func");
QScriptValue res = func.call(QScriptValue(), QScriptValueList()<<10);
if (engine.hasUncaughtException()){
qDebug()<<engine.uncaughtException().toString();
qDebug()<<engine.uncaughtExceptionBacktrace().join("\n");
} else {
qDebug()<<res.toNumber();
}
return a.exec();
}
导出C++中定义的函数script 中的 this

script 中的 this 与 C++中的有本质的区别。函数调用方式决定了this对象究竟是哪个对象。

下面一段script的代码:

var func = function(k){return k*this["val"]}
var val = 100
print(func(20))
var obj = {val:200}
print(func.call(obj, 20))
obj.f = func
print(obj.f(20))

3次调用的输出是

2000
4000
4000在C++ 中定义该函数

考虑一下:Script 中的这个函数,在C++中如何定义,并导出到 script 环境中。

var func = function(k){return k*this["val"]}

函数定义需要遵循一个统一的格式(还有一个3参数的,见Manual)

QScriptValue f(QScriptContext *, QScriptEngine *)

context 提供了函数中所需要的参数,以及this对象。

QScriptValue cppFunc(QScriptContext *ctx, QScriptEngine *eng)
{
int k = ctx->argument(0).toNumber();
int v = ctx->thisObject().property("val").toNumber();
return k*v;
}完整代码
  • 定义函数
  • 用 engine.newFunction 进行封装
  • 通过 engine.globalObject() 导出到Script脚本环境

#include /QCoreApplication>
#include /QDebug>
#include

const char script[]="var val = 100\n"
"print(func(20))\n"
"var obj = {val:200}\n"
"print(func.call(obj, 20))\n"
"obj.f = func\n"
"print(obj.f(20))";

QScriptValue cppFunc(QScriptContext *ctx, QScriptEngine *eng)
{
int k = ctx->argument(0).toNumber();
int v = ctx->thisObject().property("val").toNumber();
return k*v;
}

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QScriptEngine engine;
QScriptValue func = engine.newFunction(cppFunc);
engine.globalObject().setProperty("func", func);
engine.evaluate(script);
if (engine.hasUncaughtException()){
qDebug()<<engine.uncaughtException().toString();
qDebug()<<engine.uncaughtExceptionBacktrace().join("\n");
}
return a.exec();
}
错误与异常

script

c++

参数个数

arguments.length

ctx->argumentCount()

参数类型(比如number)

typeof arguments[0] != "number"

ctx->argument(0).isNumber()

抛出异常

throw Error("...")
throw TypeError("...")

ctx->throwError(QScriptContext::TypeError, "...")
...

阅读(2969) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~