使用PaxScript为Delphi应用增加对脚本的支持

通过使用PaxScript可以为Delphi应用增加对脚本的支持。

PaxScript支持paxC,paxBasic,paxPascle,paxJavaScript(对ECMA-262做了扩展) 四种脚本语言。它们分别是对应语言的子集。

在为程序增加脚本支持时要解决的主要问题是:本地代码与脚本之间的互相调用。

PaxScript为四种脚本语言都增加的名字空间和模块的概念。某段代码必须属于某个名字空间。执行代码时要指定代码所属的模块。默认的名字空间是全局名字空间。

Continue reading “使用PaxScript为Delphi应用增加对脚本的支持”

Phi中使用DFM文件

Delphi中有将窗体持续化的函数

  • ObjectBinaryToText: 将二进制object流转换为文本格式
  • ObjectResourceToText:将Windows资源对象流转换为文本格式
  • ObjectTextToBinary:将文本格式对象流转换为二进制格式
  • ObjectTextToResource:将文本格式对象流转换为Windows资源格式

Phi中可以加载一个DFM文件,然后动态创建DFM对应的窗体。这样就不用手工敲代码创建了。只不过DFM只能包含Phi中的控件。

Continue reading “Phi中使用DFM文件”

Setup node.js and packages for Windows

http://nodejs.org/ 上已经有多个版本的node.js for windows 的单个可执行文件.体积都很大.
有个问题至今未解决就是还没有好的npm for windows.
在npm for windows出来之前我们可以用下面的方法解决:
思路类似rubygems
按下面目录结构组织node.exe.
将bin目录加到%path%中

将各种module放到node_modules目录下,如果没有描述文件package.json,还需要手工建立
这样就可以直接在node中require(module_name)了
一般从github上下载下来的zip直接解压到node_modules下,把目录名改为模块名就ok了

更新 21:50 2011-11-14

npm已经可以顺利在windows安装了.参见官方文档

v8js引擎常用C++代码片段

/***********************************************/
/** Embedder's Guide */
/** http://code.google.com/apis/v8/embed.html **/
/***********************************************/

/**
 * Constant
 **/
v8::True();
v8::False();
v8::Null();
v8::Undefined();

/**
 * Some classes
 **/
v8::Boolean
v8::Array
v8::Arguments
v8::Date
v8::Function
v8::Int32
v8::Integer
v8::Number
v8::Object
v8::Regexp
v8::Primitive
v8::Script
v8::String
v8::Uint32
v8::TryCatch
v8::V8

/**
 * Function signature
 **/
 static v8::Handle<v8::Value> FUNCTION(const v8::Arguments& args);

/**
 * Set simple property
 **/
process->Set(String::NewSymbol("platform"), String::New(PLATFORM));

/**
 * Return object
 **/
Handle<Object> NewObj(int x) { HandleScope handle_scope; Handle<Object> obj = Object::New(); obj->Set(String::NewSymbol("name"), Integer::New(x)); return handle_scope.Close(obj);}

/**
 * Return array
 **/
Handle<Array> NewPointArray(int x, int y, int z) { 
  // We will be creating temporary handles so we use a handle scope.
  HandleScope handle_scope; 
  // Create a new empty array.
  Handle<Array> array = Array::New(3); 
  //if can not determine the length of the array just left first parameter empty 
  Handle<Array> array = Array::New(); 
  // Return an empty result if there was an error creating the array.
  if (array.IsEmpty()) return Handle<Array>(); 
  // Fill out the values 
  array->Set(0, Integer::New(x));
  array->Set(1, Integer::New(y));
  array->Set(2, Integer::New(z)); 
  // Return the value through Close. 
  return array; 
  //ERROR 
  // The Close method copies the value of its argument into the enclosing scope
  // return handle_scope.Close(array);
}
/**
 * Accessor
 * accessor callbacks are invoked when a specific object property is accessed by a script
 **/
Handle<ObjectTemplate> global_templ = ObjectTemplate::New();
global_templ->SetAccessor(String::New("x"), XGetter, XSetter);
global_templ->SetAccessor(String::New("y"), YGetter, YSetter);
Handle<Value> XGetter(Local<String> property, const AccessorInfo& info) {
  return Integer::New(x);
}
void XSetter(Local<String> property, Local<Value> value, const AccessorInfo& info) {
  x = value->Int32Value();
}
/**
 * Interceptor * interceptor callbacks are invoked when any object property is accessed by a script * named property interceptors - called when accessing properties with string names. * ndexed property interceptors - called when accessing indexed properties.
 **/
Local<ObjectTemplate> envTemplate = ObjectTemplate::New();
envTemplate->SetNamedPropertyHandler(EnvGetter, EnvSetter, EnvQuery, EnvDeleter, EnvEnumerator, Undefined());
Local<Object> env = envTemplate->NewInstance();process->Set(String::NewSymbol("env"), env); 

//Getter
static Handle<Value> EnvGetter(Local<String> property, const AccessorInfo& info) {
  String::Utf8Value key(property);
  const char* val = getenv(*key);
  if (val) { HandleScope scope;
    return scope.Close(String::New(val));
  }
  return Undefined(); 
} 

//Setter
static Handle<Value> EnvSetter(Local<String> property, Local<Value> value, const AccessorInfo& info) {
  String::Utf8Value key(property);
  String::Utf8Value val(value);
  #ifdef __POSIX__ setenv(*key, *val, 1);
  #else __WIN32__ NO_IMPL_MSG(setenv) return value;
} 

//Query
static Handle<Integer> EnvQuery(Local<String> property, const AccessorInfo& info) {
  String::Utf8Value key(property);
  if (getenv(*key)) {
    HandleScope scope;
    return scope.Close(Integer::New(None));
  }
  return Handle<Integer>();
}

//Deleter
static Handle<Boolean> EnvDeleter(Local<String> property, const AccessorInfo& info) {
  String::Utf8Value key(property);
  if (getenv(*key)) {
    #ifdef __POSIX__ unsetenv(*key);
    #else NO_IMPL_MSG(unsetenv)
    #endif
    return True();
  }
  return False();
} 

//Enumerator
static Handle<Array> EnvEnumerator(const AccessorInfo& info) {
  HandleScope scope;
  int size = 0;
  while (environ[size]) size++;
  Local<Array> env = Array::New(size);
  for (int i = 0; i < size; ++i) {
    const char* var = environ[i];
    const char* s = strchr(var, '=');
    const int length = s ? s - var : strlen(var);
    env->Set(i, String::New(var, length));
  }
  return scope.Close(env);
}
/**
 * Create function object and set it's properties
 **/

/**
 * Exception
 **/
TryCatch trycatch;
Handle v = script->Run();
if (v.IsEmpty()) {
  Handle<value> exception = trycatch.Exception();
  String::AsciiValue exception_str(exception);
  printf("Exception: %s\n", *exception_str);
  // ...
}
if (args.Length() < 3 || !args[0]->IsString() || !args[1]->IsInt32() || !args[2]->IsInt32()) {
  return ThrowException( Exception::TypeError(String::New("Bad argument")));
}
/**
 * prototype
 **/
Handle<FunctionTemplate> biketemplate = FunctionTemplate::New();
biketemplate.PrototypeTemplate().Set( String::New("wheels"), FunctionTemplate::New(MyWheelsMethodCallback))

/**
 * Inheritance
 **/
void Inherit(Handle<FunctionTemplate> parent);biketmplate.Inherit(transportTemplate);

/**
 * Parameter conversion
 **/
 //int64 
int n = args[0]->IntegerValue(); return scope.Close(Number::New(n)); 
 //int32 
int n = args[0]->Int32Value(); 
//double
double d = args[0]->NumberValue(); 
//uint32
unsigned int ui = args[0]->Uint32Value(); 
//const
char* v8::String:Utf8Value str(args[0]); const char* cstr = *str ? *str : NULL;

 

改写Array.prototype.toString

天在join(“”)一个Array的时候遇到一个问题:
当Array中还有Array的时候,嵌套的Array仍然会用逗号连接,而不是指定的空字符。比如

[1,[2,3],4].join("")

的结果是12,34
这不是我想要的。我希望得到1234
首先想到的解决办法就是递归遍历数组,如果元素是数组则对其调用join(“”)。

然后转念一想,递归调用的过程就是Array.prototype.join本身啊。我只需改写Array.prototype.toString就OK了

这是第一个版本:其问题是,如果忘记调用restore或连续调用两次Bakup就完蛋了。

var Bakup = (function(G) {
  var old = null;
  return function(who, name, to) {
    old = who.prototype[name];
    who.prototype[name] = to;
    arguments.callee.restore = function() {
      who.prototype[name] = old;
    };
  };
})();
var tag = ["<", "a ", ["href", "=\"", "http://localhost", "\""], ">"];
Bakup(Array, "toString", function() {
  return this.join("");
});
print(tag);
Bakup.restore();
print(tag);
Bakup(Array, "toString", function() {
  return this.join("-");
});
print(tag);
Bakup.restore();
print(tag);

这是第二个版本:

function Bakup(who, name, to, callback) {
  var old = who.prototype[name];
  who.prototype[name] = to;
  callback();
  who.prototype[name] = old
}
var tag = ["<", "a ", ["href", "=\"", "http://localhost", "\""], ">"];
Bakup(Array, "toString", function() {
  return this.join("");
}, function() {
  print(tag);
});
print(tag);
Bakup(Array, "toString", function() {
  return this.join("-");
}, function() {
  print(tag);
});
print(tag);

利用Delphi的Flash控件获取AS类信息

获取ActionScript 类信息的另类方法:
前一阵写了个提取 ActionScript 类中符号信息的脚本。算是可用。
用于混淆效果还行。

今天突然想到,在ActionScript中可以用

public function describeType(value:*):XML 
flash.util.describeType(KlassName)

获得类的详细信息:

  • 对象的类
  • 类的属性
  • 从类到其基类的继承树
  • 类实现的接口
  • 类的已声明实例属性
  • 类的已声明静态属性
  • 类的实例方法
  • 类的静态方法

(对于类的每个方法)名称、参数的数量、返回类型和参数类型
这样,就可以写一个类,将其他类的信息都打印出来。
但是,ActionScript工程中无法操作本地文件,只能trace到调试窗口。

Continue reading “利用Delphi的Flash控件获取AS类信息”

Posts navigation

1 2 3 4 5 6 7
Scroll to top