1

理由により、保護されたメンバーを持つ既存のスーパークラスを持ち、既存のインターフェースを実装するクラスを実行時に生成しています。インターフェイスの各メソッド (およびアクセサー) も生成する必要があります。私が苦労しているポイントは、メソッド本体を正しいオペコードで埋めることです。これは、オペコードを生成または変換したい例です。

public function myFunction(arg1:String, arg2:int):Boolean
{
    return member.my_namespace::myFunction(arg1, arg2);
}

関数の名前、引数、戻り値の型、名前空間など、すべての情報が利用可能です。as3commonsのテスト/例に見られるように、関数自体を作成してデフォルト値を返すことができます。

as3commons 以外の lib を使用する必要がありますか?

4

1 に答える 1

0

答えは自分で見つけました。私が欠けていたのは、メンバーとその機能にアクセスするための QualifiedName の (正しい) 使用だけでした。名前空間だけを削除しました。テンプレート コードで変更したのはこれだけです。

public function myFunction(arg1:String, arg2:int):Boolean
{
    return member.myFunction(arg1, arg2);
}

メソッド本体のオペコードを含むその関数を生成するために必要なソースコードは次のとおりです。

var abcBuilder:AbcBuilder = new AbcBuilder();

//build the class with the super class and the interface
var packageBuilder:IPackageBuilder = abcBuilder.definePackage("my.package");
var classBuilder:IClassBuilder = packageBuilder.defineClass("RuntimeClass", "my.package.BaseClass");
classBuilder.implementInterface("my.package.IMyInterface");

//build the function
var methodBuilder:IMethodBuilder = classBuilder.defineMethod("myFunction");
methodBuilder.returnType = "Boolean";
methodBuilder.visibility = MemberVisibility.PUBLIC;
methodBuilder.isFinal = true;

//add the parameters
methodBuilder.defineArgument("String");
methodBuilder.defineArgument("int");

//here begins the method body with the opcode
methodBuilder.addOpcode(Opcode.getlocal_0);
methodBuilder.addOpcode(Opcode.pushscope);
//call the member "member"
methodBuilder.addOpcode(Opcode.getlex, [new QualifiedName("member", LNamespace.PUBLIC)]);
//access to the function args
methodBuilder.addOpcode(Opcode.getlocal_1);
methodBuilder.addOpcode(Opcode.getlocal_2);
//call the function at the above prepared member with the prepared args
methodBuilder.addOpcode(Opcode.callproperty, [new QualifiedName("myFunction", LNamespace.PUBLIC), 2]);
//return the result
methodBuilder.addOpcode(Opcode.returnvalue);

//fire at own will
abcBuilder.addEventListener(Event.COMPLETE, loadedHandler);
abcBuilder.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
abcBuilder.addEventListener(IOErrorEvent.VERIFY_ERROR, errorHandler);
abcBuilder.buildAndLoad();

コードが機能することを保証するものではありません。私はそれが非常にうまく機能する自分のプロジェクトでいくつかの動的なものとループでそれを調整しました。私が使用するライブラリ(d)は次のとおりです。

  • as3commons-bytecode-1.1.1
  • as3commons-lang-0.3.7
  • as3commons-logging-2.7
  • as3commons-reflect-1.6.4

as3commonsのダウンロードですべて入手可能

于 2015-12-29T21:00:18.877 に答える