外部ライブラリとの連携のためのパッケージです。
PC版, Mobile版ではMicrosoft .NET Framework(以下.NET) と連携し、.NET外部オブジェクトの生成、および実行のためのクラスが用意されています。
Android版ではAndroid標準ライブラリと連携し、Java外部オブジェクトの生成、および実行のためのクラスと、他のAndroidアプリに対しインテントを発行するためのクラスが用意されています。
名前 |
説明 |
Version |
||
PC |
Mobile |
AI |
||
(.NET連携用) |
.NETオブジェクトを保持します |
5.0.0 |
3.1.0 |
- |
(.NET連携用) |
.NETデータ型を一致させるためのクラスです |
5.0.0 |
3.1.0 |
- |
(Java連携用) |
Javaオブジェクトを保持します |
- |
- |
1.0.0 |
(Java連携用) |
Javaデータ型を一致させるためのクラスです |
- |
- |
1.0.0 |
他のアプリに対しインテントを発行するためのクラスです |
- |
- |
1.0.1 |
Biz/Browser V, Biz/Browser AIでは、ExternalObjectパッケージの利用はセキュリティレベルによって制限されています。ExternalObjectパッケージはセキュリティレベルを0に設定することで利用できます。
セキュリティレベル1以上では、ExternalObjectパッケージのクラスをインスタンス化しようとしたときに例外が発生します。
.NET連携機構について(PC版、Mobile版)
このパッケージを用いることにより.NETで作成されたDLLクラスライブラリや、.NETビルトインクラスの機能を利用することが可能になります。
利用には.NET (Compact) Framework 2.0以上が必要です。
CRSから.NETオブジェクトへ値を渡す場合、また逆に.NETオブジェクトから結果を受け取る場合、それぞれの言語のデータ型に自動的に変換が行われます。
変換ルールは以下のようになります。
CRS型 |
.NET型(名前空間は省略) |
Stringまたは文字列リテラル |
String |
Number(小数点以下を含まない場合) 整数リテラル(true=1、false=0を含む) |
Int32 |
Number(小数点以下を含む場合) 小数点付き数値リテラル |
Double |
Date |
DateTime |
null |
null |
ExternalObject |
ExternalObjectが所有している.NETオブジェクト |
.NET型(名前空間は省略) |
CRS型 |
Int32、UInt32、Boolean、Int16、UInt16 Byte、SByte、Char、IntPtr、UIntPtr |
整数型 |
Int64、UInt64 より拡張されました |
|
String |
String |
DateTime |
Date |
Byte[] |
String |
Double、Single |
Number |
null |
null |
Enum値 |
整数型 |
その他の型 |
ExternalObjectにてラップ |
前述の通りCRSがサポートしているデータ型は.NETのそれよりも種類が少ないため、.NETのプロパティやメソッドを呼び出す際に、CRSのデータ型では表現できない場合があります。(Booleanなど)
その場合は、ExtValクラスを用いて.NETに渡したい値をラップすることで対応できます。
例)true(=整数1)をBoolean型として設定
var ret = extobj.SetProperty("SampleProp", new ExtVal(true, ExtVal.Boolean));
ユーザーがクラスライブラリDLLを作成する際、Biz/Browserからインスタンスを作成できるクラスはPublicクラス、呼び出し可能なメソッドはPublicメソッドとして定義してください。
作成したDLLは、Biz/Browserインストールフォルダに"dll.net"という名前のフォルダを作成し、その下に配置してください。
例)
(Biz/Browserインストールフォルダ)\dll.net\sample.dll
.NETオブジェクトの生成時や、スタティックメソッドの呼び出しでは、.NETクラスが定義されているライブラリを指定します。
ユーザークラスライブラリDLLに定義されたクラスを指定する場合は、DLLファイル名のみ記述します。(ファイルパスは不要です)
指定されたDLLファイルは、Biz/Browserインストールフォルダにある"dll.net"フォルダから検索されます。
よりDLLへの絶対パスが指定できるようになりました。dll.netフォルダ以外に配置されたDLLも指定できます。
例)
var extobj = new ExternalObject("SampleNS.SampleClass", "sample.dll")
mscorlibアセンブリにある基本クラスは、ライブラリは不要なのでnullを指定します。
例)
var ret = ExternalObject.InvokeStatic("System.Math", null, "Pow", 2, 10);
print(ret, "\n");
その他のグローバル・アセンブリ・キャッシュに登録されているライブラリを使用する場合は、厳密な名前でアセンブリを指定します。
例)
var lib = "System.Windows.Forms, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089";
ExternalObject.InvokeStatic("System.Windows.Forms.MessageBox", lib, "Show", "abc");
.NETクラスのコンストラクタやメソッドの引数に指定できるものには、CRSの一般的な型やリテラル、ExternalObjectオブジェクト、ExtValオブジェクトがあります。
引数はCRSと.NET間の型変換のルールに従い.NET型に変換されて渡されます。
例)
数値リテラルをそのまま指定する
var extobj = new ExternalObject("System.Random", null, 999);
var ret = extobj.Invoke("Next", 0, 100);
print(ret, "\n");
文字列型の変数を指定する
var str = "TMP";
var ret = ExternalObject.InvokeStatic("System.Environment", null, "GetEnvironmentVariable", str);
print(ret, "\n");
ExtValクラスを使って.NET型を指定する
var v = new ExtVal(true, ExtVal.Boolean);
var ret = ExternalObject.InvokeStatic("System.Convert", null, "ToString", v);
print(ret, "\n");
ExtValクラスを使って.NET列挙体を指定する
var lib = "System.Windows.Forms, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089";
var buttons = new ExtVal("System.Windows.Forms.MessageBoxButtons.OK", ExtVal.Enume, lib);
var icon = new ExtVal("System.Windows.Forms.MessageBoxIcon.Asterisk", ExtVal.Enume, lib);
ExternalObject.InvokeStatic("System.Windows.Forms.MessageBox", lib, "Show", "ABC", "123", buttons, icon);
値に変換できないその他のCRSオブジェクトや参照を指定した場合はエラーになります。
コンストラクタ、メソッドの呼び出しでは、呼び出し先で定義されているすべての引数の型と完全に一致している必要があります。(参照型、値型の違いも含む)
クラス名、メソッド名、すべての引数の型が一致しない場合は、呼び出し先を見つけることができずにエラーとなります。
より参照型の引数を指定できるようになりました。以下の仕様が追加されています。 -->。
参照型の引数を指定する場合は、ExtValクラスのデータ型の指定にExtVal.ByRefを組み合わせます。
例)
var v1 = new ExtVal("abc", ExtVal.String + ExtVal.ByRef);
var v2 = new ExtVal("xyz", ExtVal.String + ExtVal.ByRef);
ExternalObject.InvokeStatic("SampleNS.SampleClass", "sample.dll", "Swap", v1, v2);
print(strf("v1=%1 v2=%2", v1, v2), "\n");
<-- ここまで
ExternalObject.Invokeメソッド、またはExternalObject.InvokeStaticメソッドでは、.NETクラス側で発生したユーザー例外を捕捉することができます。
対象となるメソッド内でSystem.ApplicationExceptionクラスまたはその派生クラスを例外としてスローすると、Biz/Browserでは通常のエラー時の例外とは区別した例外(EXTOBJ-6)が発生します。
CRSの例外オブジェクトには子オブジェクトExtExceptionが付加されます。ExtExceptionは.NET側でスローした例外を保持するExternalObjectオブジェクトです。
この機構によりCRSから.NETの例外クラスにアクセスして情報を取得することができます。
例)ユーザー例外を捕捉
try {
var extobj = ExternalObject.InvokeStatic("SampleNS.SampleClass", "sample.dll");
extobj.Invoke("SampleMethod");
} catch (e) {
if (e.Method == "EXTOBJ" && e.Code == 6) {
MessageBox(e.ExtException.GetProperty("Message"));
}
}
ネイティブアプリケーションであるBiz/BrowserまたはBiz/Browser Mobile(以下Biz/Browser)から直接.NETライブラリを呼び出すことは通常できません。そのため.NETで作成されたサブプログラム(invoker.exe)を介して.NETのオブジェクトを操作しています。
invoker.exeはExternalObjectクラスにより.NETオブジェクトの操作が行われる初回に自動的に起動し、Biz/Browser終了時に自動的に終了します。ユーザーはinvoker.exeの存在を意識する必要はありません。
invoker.exeはBiz/Browserの監視下に置かれており、invoker.exeに何らかの問題が起こり実行が中断された場合、CRSの例外としてエラー報告されます。
ExternalObjectクラスは.NETオブジェクトに一対一で対応し.NETインスタンスの生成と消滅、プロパティやメソッドへのアクセスを提供するラッパーおよびリダイレクタとしての機能を有しています。ExternalObjectクラスは内部で自動的にinvoker.exeと連携し、あたかもBiz/Browserから直接.NETオブジェクトを操作しているよう振る舞います。
invoker.exeはデバッグ機能としてログ出力機能を持っています。
invoker.exeと同じフォルダに"logging.on"という名前のファイルを配置するとinvoker.exeはinvokerlog.txtという実行ログファイルを出力します。logging.onファイルはファイルさえあれば0バイトでも構いません。
Java連携機構について(Android版)
CRSからJavaオブジェクトへ値を渡す場合、また逆にJavaオブジェクトから結果を受け取る場合、それぞれの言語のデータ型に自動的に変換が行われます。
変換ルールは以下のようになります。
引数の受け渡し時やフィールドへの設定時などに適用されるルールです
◇ExtValを渡した場合
変換元(CRS) |
変換先(Java) |
ExtVal.Boolean |
boolean型 (プリミティブ型) |
ExtVal.Char |
char型 (プリミティブ型, 2byte符号付き整数, 文字表現用) |
ExtVal.Byte |
byte型 (プリミティブ型, 1byte符号付き整数) |
ExtVal.Short |
short型 (プリミティブ型, 2byte符号付き整数) |
ExtVal.Int |
int型 (プリミティブ型, 4byte符号付き整数) |
ExtVal.Long |
long型 (プリミティブ型, 8byte符号付き整数) |
ExtVal.Float |
float型 (プリミティブ型, 4byte単精度浮動小数点数) |
ExtVal.Double |
double型 (プリミティブ型, 8byte倍精度浮動小数点数) |
◇CRSオブジェクトを渡した場合
変換元(CRS) |
変換先(Java) |
Number |
整数値ならばint型 小数点以下の値を保つ場合double型として解釈 |
Date |
java.util.Dateクラス |
String |
java.lang.Stringクラス |
ByteArray |
byte[]型 |
ExternalObject |
格納されているインスタンスのクラス |
その他(nullを含む) |
例外発生(型解決不能) |
メソッドの戻り値やフィールドからの取得時などに適用されるルールです。
◇プリミティブ型を受け取った場合
変換元(Java) |
変換先(CRS) |
boolean型 |
trueならば1, falseならば0 |
char型 |
整数値 |
byte型 |
整数値 |
short型 |
整数値 |
int型 |
整数値 |
long型 |
整数値 (4byte符号付き整数が表現できる範囲に切り詰められます) |
float型 |
Numberオブジェクト |
double型 |
Numberオブジェクト |
◇参照型を受け取った場合
変換元(Java) |
変換先(CRS) |
null値(型によらず) |
null値 |
java.lang.String |
Stringオブジェクト |
byte[] |
ByteArrayオブジェクト |
その他オブジェクト |
ExternalObjectオブジェクト |
Java言語における型は大きく分けて「プリミティブ型」と「参照型」に別れます。
ExternalObjectパッケージのJava連携機能ではExtValクラスがプリミティブ型を、ExternalObjectクラスが参照型をそれぞれラップします。
Java言語では、プリミティブ型をObject型を継承する参照型に変換することを「ボックス化(boxing)」と呼びます。
例として、int型の値をjava.lang.Integerクラスのインスタンスに変換する処理が相当します。
また、参照型をプリミティブ型に変換することを「ボックス化解除(unboxing)」と呼びます。
例として、java.lang.Doubleクラスのインスタンスをdouble型の値に変換する処理が相当します。
ボックス化及びボックス化解除は、通常Javaコンパイラによって自動的に行われるものですが、ExternalObjectのJava連携を使用する場合は明示的に行う必要があります。
CRSにおいては、ボックス化にはExtVal.Boxingメソッドを、ボックス化解除にはExternalObject.Unboxingメソッドを使用します。
Javaプリミティブ型と、それに対応するJava参照型の対応は下記のとおりです。
ボックス化,ボックス化解除におけるプリミティブ型と参照型の対応
ExtVal.Typeの値 |
ExtVal.Typeが示す プリミティブ型 |
対応するJava参照型 |
ExtVal.Boolean |
boolean型 |
java.lang.Booleanクラス |
ExtVal.Char |
char型 |
java.lang.Characterクラス |
ExtVal.Byte |
byte型 |
java.lang.Byteクラス |
ExtVal.Short |
short型 |
java.lang.Shortクラス |
ExtVal.Int |
int型 |
java.lang.Integerクラス |
ExtVal.Long |
long型 |
java.lang.Longクラス |
ExtVal.Float |
float型 |
java.lang.Floatクラス |
ExtVal.Double |
double型 |
java.lang.Doubleクラス |
ExternalObjectパッケージではExternalObject.LoadJarメソッドを用いて外部Jarファイルをロードすることができます。
この時に指定するライブラリIDはロードされたJarファイル内のクラス情報を保持するクラスローダを管理するための値です。他のライブラリと被らない空ではない非nullの文字列を指定します。
ライブラリIDが使用されているかを調べるにはExternalObject.IsLibraryIdUsedメソッドを使用してください。
AndroidのDalvik仮想マシンはPC用(一般的なJava)のjarファイルをそのまま実行できないため、作成したjarファイルをAndroid SDK付属のツール(dxコマンド)を使用しAndroidが解釈できる形式に変換する必要があります。
ExternalObjectコンストラクタやExternalObject.InvokeStaticメソッドなどでクラスを指定する際にロード時と同じライブラリIDを指定することで、そのクラスローダからクラス情報を読み出します。
なお、クラス名(完全限定名)が同じクラス,インタフェースでもライブラリIDが異なる場合、異なる型として扱われます。
Androidが元々ロードしているクラス(java.lang.Stringやandroid.graphics.Point)等はシステムクラスローダが
管理しています。これらのクラスを利用する場合、ライブラリIDにnullを指定してください。
Biz/Browser AIは他の一般的なAndroidアプリ同様、機能を実現するためにAndroid OSに対しパーミッションと呼ばれるものを要求します。
パーミッションはAndroidアプリがどのような機能に対してアクセスする可能性があるかを明示するもので、Androidアプリのインストール時にその一覧が表示されます。
Androidアプリは要求したパーミッション以外の機能にアクセスすることはAndroid OSによって禁止されます。
そのため、ExternalObjectクラスを用いてAndroid標準ライブラリやJarファイルの形で提供されるライブラリ等を使用する場合、Biz/Browser AIに付与されているパーミッションで可能な範囲の処理となっている必要があります。
ライブラリを使用する前に予め必要となるパーミッションをご確認下さい。
Biz/Browser AIがAndroidOSに対して要求するパーミッションはAndroid版の特徴と制約に記載されています。
Javaクラスのコンストラクタやメソッドの引数に指定できるものには、CRSの一般的な方やリテラル、ExternalObjectオブジェクト、ExtValオブジェクトがあります。
引数はCRSとJava間の型変換のルールに従いJavaプリミティブ型またはJava参照型に渡されます。
例)
数値リテラルをそのまま指定する
var extobj = new ExternalObject("java.util.Random", null, 999);
var ret = extobj.Invoke("nextInt", 100);
print(ret, "\n");
文字列型の変数を指定する
var str = "TMP";
var ret = ExternalObject.InvokeStatic("java.lang.System", null, "getenv", str);
print(ret, "\n");
ExtValクラスを使ってJavaプリミティブ型を指定する
var v = new ExtVal(true, ExtVal.Boolean);
var ret = ExternalObject.InvokeStatic("java.lang.Boolean", null, "toString", v);
print(ret, "\n");
ExternalObjectクラスを使ってJava参照型を指定する
var v1 = new ExternalObject("android.graphics.Point", null, 10, 20);
var v2 = new ExternalObject("android.graphics.Point", null, 30, 40);
var ret = v1.Invoke("equals", v2);
print(ret, "\n");
ExternalObject.Castメソッドを使って型変換したJava参照型を指定する
var extobj1 = new ExternalObject("java.io.FileOutputStream", null, "/sdcard/test.txt");
var extobj2 = new ExternalObject("java.io.BufferedOutputStream", null, extobj1.Cast("java.io.OutputStream"));
/* … */
extobj2.Invoke("close");
extobj1.Invoke("close");
値に変換できないその他のCRSオブジェクトや参照を指定した場合はエラーになります。
コンストラクタ、メソッドの呼び出しでは、呼び出し先で定義されているすべての引数の型と完全に一致している必要があります。(参照型、値型の違いも含む)
参照型の場合、要求されているクラスの派生クラスを渡す場合は明示的にExternalObject.Castメソッドを呼び出し基底クラスへの参照に変換する必要があります。
また、null値を指定する場合、ExternalObject.NullRefメソッドを用いて型情報を持つnull参照を作成する必要があります。
プリミティブ型の場合、暗黙的な値のワイドニング変換、ナローイング変換は行われません。ExtValオブジェクトを用いて明示的に要求されている型を指定してください。
ボックス化(boxing)や参照型のボックス化解除(unboxing)は明示的に行う必要があります。ボックス化及びボックス化解除につきましてはプリミティブ化とボックス化を参照してください。
クラス名、メソッド名、すべての引数の型が一致しない場合は、呼び出し先を見つけることができずにエラーとなります。
ExternalObject.Invokeメソッド、またはExternalObject.InvokeStaticメソッドでは、Javaクラス側で発生した例外を捕捉することができます。
対象となるメソッド内で例外をスローすると、Biz/BrowserではInvokeおよびInvokeStaticに失敗したことを示すEXTOBJ-4例外が発生します。
CRSの例外オブジェクトには子オブジェクトExtExceptionが付加されます。ExtExceptionはJava側でスローした例外を保持するExternalObjectオブジェクトです。
この機構によりCRSからJavaの例外クラスにアクセスして情報を取得することができます。
例)例外を捕捉
try {
var extobj = ExternalObject.InvokeStatic("sampleNS.SampleClass", "sampleLib");
extobj.Invoke("SampleMethod");
} catch (e) {
if (e.Method == "EXTOBJ" && e.Code == 4) {
MessageBox(e.ExtException.Invoke("toString"));
}
}
なお、EXTOBJ-4例外以外でもEXTOBJ例外オブジェクトの子オブジェクトとしてExtExceptionが付加される場合があります。
ExtExceptionが付加されているかを調べるにはObject.FindChildを使用します。
Biz/Browser AIは一般的なAndroidアプリケーションと同じくDalvik仮想マシン上(一部ネイティブコード)で動作しています。
そのため、ExternalObjectのJava連携機能ではJavaの機能の一部であるリフレクションを用いることでJavaのオブジェクトを操作しています。
PC版、Mobile版とは異なり、JavaオブジェクトはBiz/Browserと同じメモリ空間に作成されます。
そのため、Javaオブジェクト内で大量のメモリ確保を行った場合Biz/Browser自体がメモリ不足で停止する可能性がありますためご注意ください。
また、Biz/Browserの動作保護のため、jp.co.axissoft.biz名前空間のオブジェクトに対する操作を禁止しています。
この名前空間のオブジェクトに対し操作を行った場合、EXTOBJ-11例外が発生します。
Java連携機能はデバッグ機能としてログ出力機能を持っています。
“/sdcard/Android/data/jp.co.axissoft.biz/files”フォルダに".logging.on"(ファイル名先頭のドットにご注意ください)という名前のファイルを配置するとBiz/Browserは同じディレクトリに”ExternalObject.log”という実行ログファイルを出力します。”.logging.on”ファイルはファイルさえあれば0バイトでも構いません。