|
2.12 マークを使う
MathLink を使うとリンクに「マーク」を設定することができるので,よりたくさんのデータを読み,マークに戻りデータを読む前の状態にリンクを復元することができます.このように,マークによってリンクからデータを読み,データが消去されないようにすることができるので,後でまたデータを読むことも可能です.MathLinkインターフェースには3つのマーク関連のメソッドがあります.
//In the MathLink interface:
long createMark() throws MathLinkException;
void seekMark(long mark);
void destroyMark(long mark);
マークを使うのは,着信の式を調べ,式の属性に従って異なるコードに分岐したい場合が一般的です.式全体を見るために実際に式を扱うコードが必要ですが,どのように扱われなければならないかを決めるために少なくとも式を部分的に読まなければなりません(おそらくgetFunction()を呼び出して頭部を見るだけでよいでしょう).これがこのテクニックを例示するコードの一部です.
String head = null;
long mark = ml.createMark();
try {
head = ml.getFunction().name;
ml.seekMark(mark);
} finally {
ml.destroyMark(mark);
}
if (head.equals("foo"))
handleFoo(ml);
else if (head.equals("bar"))
handleBar(ml);
getFunction()を呼び出した後マークに戻るので,リンクは handleFoo()とandleBar()メソッドが入力されたときに式の最初にリセットされます.マーク生成後にどんな例外が投げられたとしても,マークがいつも確実に破壊されるようにするためにtry/finallyブロックを使うことにご注意ください.マークはいつもこのように使わなければなりません.createMark()を呼び出した直後,finally節がdestroyMark()を呼び出すtryブロックを始めます.createMark()とtryブロックの間には他のコード,特にMathLink の呼出し(これはMathLinkExceptionを投げます)が介入していないことが大切です.マークが生成されて破壊されなければ,着信データがリンクに山積みになり解放されないので,メモリリークが起きます.
マークを使うと,式をある方法で読み,MathLinkExceptionが投げられたら戻って違う方法で読むこともできます.例えば,実数のリストがリンクで待っていると想定しているとします.マークをセットしgetDoubleArray1()を呼び出すことができます.リンクのデータが実数のリストに強制できなければ,getDoubleArray1()はMathLinkExceptionを投げます.するとマークに戻り,違う方法でデータを読むことができます.
double[] data = null;
long mark = ml.createMark();
ty {
data = ml.getDoubleArray1();
} catch (MathLinkException e) {
ml.clearError();
ml.seekMark(mark);
// Here, try a different way of reading the data:
switch (ml.getNext()) {
...
}
} finally {
ml.destroyMark(mark);
}
マークの機能のほとんどは2.14で説明されるExprクラスによって包括されています.Exprオブジェクトにより,式を異なる方法で何度でも調べられるようになります.peekExpr()メソッドを使うと,近づいてくる式をリンクから消さないで簡単に前もって見ることができます.
|