HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2019
0329
mzkHSP3dishにおける#defcfunc内での条件分岐によるユーザー関数の呼び出し11解決


mzk

リンク

2019/3/29(Fri) 17:35:21|NO.86987

HSP3dishの基本ガイドの既知の不具合に、
・#defcfuncによるユーザー定義関数の呼び出し内で、awaitやwait、stopなど
 タスクが停止状態になる命令を実行するとエラー(40)が発生しますので使用を避けてください。
・#defcfunc、#deffunc命令によるユーザー定義呼び出し先でgosub命令を使用した際に、
 呼び出し先のサブルーチンで引数にアクセスできない不具合が報告されています。
とありますが、類似のエラーだと思われますので報告します。

以下のスクリプトは#defcfunc内でif文によって別のユーザー関数を呼び出しています。
windows上のF5でのrunでは問題なく実行されますが、
android実機ではif文の辺りでプログラムが強制終了してしまいます。


#include "hsp3dish.as" goto *main #defcfunc aaa int a, int b return a+b #defcfunc bbb int c, int d if c==1{ bb = aaa(c,d) } return bb *main repeat redraw 0 pos 0,0 color 255,0,0 mes bbb(1,1) redraw 1 await 10 loop

switch/caseで分岐させても同様に強制終了してしまいます。
logcatではエラー(40)が出ています。

皆さま、同様のエラーが出ますでしょうか?
サブルーチンで書けば回避できそうですが、変数のやり取りが大変そうです。
何か良い回避方法はありますでしょうか?



この記事に返信する


ドナルド

リンク

2019/3/29(Fri) 17:52:04|NO.86988

#module
~
#global
で囲まないんですか?
これで解決できるかはわからないけど



mzk

リンク

2019/3/29(Fri) 18:35:03|NO.86989

ドナルドさん

モジュールにするかどうかは関数内の変数に外からアクセスするかどうかによるので、
ケースバイケースだと思います。
強制終了についてはモジュールにしても変わらず起きてしまいました。



沢渡

リンク

2019/3/29(Fri) 18:35:40|NO.86990

HSP3dishはかなり無理矢理な方法でAndroid向けビルドをしているせいか、
「マクロを使うなどして入り組んだ式を計算させる」
「関数から関数を呼び出す」などといった複雑なことをやると、
「Windowsでは正常に動くのに、実機では落ちる」ということがよくあります。
不具合ではあるでしょうが、仕様上どうしようもないんじゃないかな、
とは思います。

何度も実機やエミュレータでテストし、落ちるようなら落ちる場所を特定して、
「複数に分けて計算させる」とか「関数から関数を呼び出すのを避ける」などして
複雑な処理を単純化するような対策が必要になるでしょう。

>NO.86988

「#module〜#global」は関係ないんじゃないでしょうか。 自作関数であっても、モジュール空間に置いた方が都合がいい場合と グローバル空間に置いた方が都合がいい場合とがありますし、 グローバル空間に置いたせいで落ちた記憶はありませんので。



ドナルド

リンク

2019/3/29(Fri) 22:04:25|NO.86995

そうでしたか
書かないと勝手に実行されて困っていたのでいるものだと勘違いしていました
gotoを使う手があったとは



mzk

リンク

2019/3/30(Sat) 13:11:47|NO.86998

沢渡さん

ありがとうございます。
細かく実機で確認をしながら進めてみます。



ぜーっと!

リンク

2019/4/6(Sat) 15:35:20|NO.87096

こにちは。久々に来てみました。

不具合報告ということなので、dish自体の修正以外に解決策を望んでいるのかはわかりませんが、
昨年リリースした「てととと」アプリを作る際、バーチャルパッドモジュールを作成中
同じように困った記憶があります。

メインルーチンから一つ一つを呼び出すのは、結構面倒なうえ、メインが肥大化して
ごちゃごちゃするので極力さけたいところです。

たしかに
× メインルーチン → defcfunc関数 → defcfunc関数
× メインルーチン → defcfunc関数 → deffunc命令
はdefcfunc関数からさらに別の関数呼び出しは仕様(?)のようでできないようです。落ちます。

できないならば、違う方法を探ればいいのです。
調べてみると
〇 メインルーチン → deffunc命令 → defcfunc関数
〇 メインルーチン → deffunc命令 → deffunc命令
の実行はできるようなので、この方法を利用すれば、必要としてる処理と結果は取得できると思います。
幸い、deffunc命令でもmrefを使用すれば、戻り値をstatで返せるので、

#include "hsp3dish.as"
goto *main #module #defcfunc aaa int a, int b return a+b #deffunc bbb int c, int d mref ret, 64 //statを使用する ret = 0 //明確な初期化 if c==1 { ret = aaa(c,d) //関数実行 } return #global *main repeat redraw 0 pos 0,0 color 255,0,0 bbb 1,1 r = stat //statから戻り値をもらう mes ""+ r redraw 1 await 10 loop

元の流れとそれほど変わってないと思います。
#module〜#globalはお好みで。
変数衝突困るなら付けた方が良いです。

それ以外では、モジュール内にゲッター、セッターを置く方法です。
私はこちらでやってます。



mzk

リンク

2019/4/6(Sat) 20:49:46|NO.87099

ありがとうございます。
結局サブルーチンからdefcfunc呼び出しにして進めています。
現状ではdefcfuncからdefcfuncを呼ぶこと自体がエラーではなく、
defcfunc内の条件式でdefcfuncを呼び出すとどこかで戻り値が取れなくなってしまうようです。
原因が分かると回避方法も考えられるのですが、
どこにエラーがあるか分からない状態だと気付くまでに時間がかかってしまいました…。
同じ用な問題で原因が分からない方のお役に立てれば幸いです。



ぜーっと!

リンク

2019/4/6(Sat) 23:00:32|NO.87102

>現状ではdefcfuncからdefcfuncを呼ぶこと自体がエラーではなく、
>defcfunc内の条件式でdefcfuncを呼び出すとどこかで戻り値が取れなくなってしまうようです。

ありゃ、ほんまですね(汗)if分岐させずに関数呼び出してみたらできました。
自分のモジュールもif分岐からの関数呼び出しで落ちる流れだったんですねー。

とはいえ、大抵は分岐使う状況多いわけですし、他の方法で乗り切り(誤魔化し)ましょうw。



mzk

リンク

2019/4/8(Mon) 09:15:20|NO.87112

ぜーっと!さん

ゲッター、セッターを使うというのは、
引数でvarを渡してそこに代入させるという事でしょうか?



ぜーっと!

リンク

2019/4/10(Wed) 21:00:30|NO.87126

どもども。返信に気づかず(^^;

>引数でvarを渡してそこに代入させるという事でしょうか?
参照渡しで、変数に書き込むのも一つの方法だと思います。
自身の使いやすい、かつ不具合の起きにくい方法で乗り切ればいいと思います。

私のやり方は、たいしたことはやってなくて、至極単純な方法です。
モジュールを他のゲームでも再利用するためにゲッターセッター方式にしてることが多いです。
複数のモジュールを使うことが多く、変数の衝突を避けるため、
各々moduleにして封じ込めて、必要な情報はメインから問い合わせる形ですね。

mzkさんのサンプルを使うと以下のような感じで、
#include "hsp3dish.as"
goto *main #module #deffunc init_ret //ret初期化 ret = 0 //モジュール内では保持されている return #defcfunc aaa int a, int b return a+b #deffunc bbb int c, int d if c==1 { ret = aaa(c,d) //関数実行 } return #defcfunc get_ret //ゲッター return ret #global *main init_ret //モジュール内変数初期化(最初のみ) repeat redraw 0 pos 0,0 color 255,0,0 bbb 1,1 r = get_ret() //ゲッターから戻り値をもらう mes ""+ r redraw 1 await 10 loop

メインからdefcfunc関数にアクセスしても、数値を返すだけなので問題ないです。

拙作「てとととと」では入力用仮想パッドモジュール内で活躍してます。
方向キー入力とボタン入力を保持し、メインからの問い合わせに答える流れです。



mzk

リンク

2019/4/10(Wed) 21:55:05|NO.87127

なるほど、
計算してセットするだけの関数とゲットするためだけの関数に分けるんですね。
参考になります。



ONION software Copyright 1997-2018(c) All rights reserved.