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


HSPTV!掲示板


未解決 解決 停止 削除要請

2007
0725
SOU1float型の返り値を取得したい18停止


SOU1

リンク

2007/7/25(Wed) 14:27:17|NO.9727

強引にでも良いのでfloat型の返り値を取得する方法は無いものでしょうか?
具体的にはbass.dllのBASS_ChannelBytes2Secondsを使おうとして躓いています。

float BASS_ChannelBytes2Seconds(
DWORD handle, QWORD pos );

QWORDはsptr,sptr,nullptr等指定して無理矢理送りつける事が出来たのですが、
stat等には何も返っていないようです。



この記事に返信する


eller

リンク

2007/7/25(Wed) 16:20:09|NO.9730

DLLは詳しくないのでわかりませんが、実数型の戻り値ならstatではなくrefdvalに格納されるようです。
一度そちらを調べてみてはいかがでしょうか?



SOU1

リンク

2007/7/25(Wed) 16:50:37|NO.9732

先に書いておけば良かったのですが、
refdval/refstrにも何も返ってきていないようです。
refdvalは名前からしてdouble型の返り値が格納されるのかと思います。

自分が他に何らかのミスをしている可能性もありますが、
とりあえず他の関数でQWORDをint型二つで偽装するのは上手くいっているようです。



f

リンク

2007/7/26(Thu) 08:42:30|NO.9743

・・・こんな感じでDLLをラップするDLLを作るというのは・・・・(本末転倒

C側
INT WINAPI Test(double *ret)
{ float dataf = (float)3.141592; double datad = (double)dataf; *ret = datad; return 0; }


HSP側
#uselib "***.dll"
#cfunc test "Test" var data = 0.0 ret = test( data ) mes data stop



eller

リンク

2007/7/26(Thu) 11:35:09|NO.9749

何らかの形で取得さえできればfloat型をdouble型へ変換することはHSPでもできるのですが(sprocketさんのウェブサイトを参照)、なにも返っていないとそれも無理ですね。

きちんと調べたわけではありませんが、HSPからbass.dllを利用するためのdll
http://www.vector.co.jp/soft/win95/prog/se136808.html
なんてのもあるらしいので、これを使った方が早いのでは?



f

リンク

2007/7/26(Thu) 12:34:51|NO.9751

ためしにDLLこさえてみたら、

C側
float WINAPI test(double data)
{ return ((float)data); }

HSP側
#uselib "test.dll"
#cfunc Test "test" double dupptr fl , Test( 10.10 ) , 4 , 3 mes fl

これで取得できた。
変な数字が帰ってくると思ったら、戻り値はアドレスみたいだ。



SOU1

リンク

2007/7/26(Thu) 14:16:46|NO.9761

> eller さん
bass4hspはhsp2用で、かつbassの機能を全て使えるわけでもないので
プラグインを利用したり最新の機能が使えないので除外していました。
sprocketさんのモジュールは既に利用させて頂いています。

> f さん
同じようにdupptrを利用してやってみたところ、
確かにアドレスらしき何らかの値を取得出来たのですが、
mes行で落ちたりデバッグ窓が落ちたりと妙に不安定になってしまいました。
多少試行錯誤してみます。

最悪安定するのであればラップするDLLでも構わないかな、とは思っていたのですが
とりあえずDLLの作り方から勉強する事になりそうです……



f

リンク

2007/7/26(Thu) 14:26:39|NO.9763

本来8バイトのサイズが必要な場所に4バイトしか書いてないからかね。
一度0クリアしてから書き込むべきか。

それとも根本的に他の問題があるのか。

自分程度のへっぽこではこれ以上分からないかもしれない。



YOYO

リンク

2007/7/27(Fri) 01:28:25|NO.9784

整数と小数では返り値を渡す仕組みが異なるのでプラグインかマシン語で取り出す仕組みが必要です。
強引ですが、関数の返した小数を取り出すモジュールを作ってみました。
関数が返す少数はdoubleとfloatどちらでも大丈夫です。

#module #uselib "kernel32.dll" #func VirtualProtect "VirtualProtect" int, int, int, int #deffunc getdouble if code == 0 { code=$0424448b,$04c218dd,$00000000 VirtualProtect varptr(code), length(code)*4, $40, varptr(res) fret=0.0 } prm = varptr(fret) res = callfunc(prm, varptr(code), 1) return fret #global BASS_ChannelBytes2Seconds handle,pos getdouble //getdoubleは小数を返す命令の直後に呼び出してください。 mes refdval



f

リンク

2007/7/27(Fri) 10:15:17|NO.9792

おおお。
これは良い。使わせて貰お(ヲ



SOU1

リンク

2007/7/27(Fri) 10:36:46|NO.9793

> YOYO さん
うぉぉぉぉすげー一発で取得出来ました
汎用性もありそうなので、今後大いに利用させて頂くと思います
本当にありがとうございました



eller

リンク

2007/7/27(Fri) 15:20:30|NO.9799

おおっ、鮮やかですね。こういったスクリプトが理解できるようになりたいものです。



Shinya

リンク

2007/7/27(Fri) 16:40:18|NO.9804

横から失礼します。
>code=$0424448b,$04c218dd,$00000000
7-9byteめの C20400(LE) は自前でスタックを戻すコードですが、個人的にはc3としたいです。
#module
#uselib "kernel32.dll" #func VirtualProtect "VirtualProtect" int,int,int,int #deffunc _INITCODE_ code = $000000b8,$c318dd00,$000000b8,$c318d900 VirtualProtect varptr(code), length(code)*4, $40, varptr(res) dret = 0.0 : fret = 0.0 return ; double型で戻り値を得る #defcfunc GetDST lpoke code, 1, varptr(dret) : res = callfunc(res, varptr(code), 0) return dret ; float型で戻り値を得る #defcfunc GetFST lpoke code, 9, varptr(fret) : res = callfunc(res, varptr(code)+8, 0) return fret ; ---------------------------- ; test func ; ---------------------------- #deffunc SetST var dv; double test = $000000b8,$c300dd00:VirtualProtect varptr(test), length(test)*4, $40, varptr(res) lpoke test, 1, varptr(dv) :res = callfunc(res, varptr(test), 0) return ; ---------------------------- #global _INITCODE_ d = 10.0 : SetST d : mes GetDST() ; BASS_ChannelBytes2Seconds handle,pos ; mes GetDST()



f

リンク

2007/7/27(Fri) 17:05:33|NO.9806

HSPとはもう関係ない世界なので、
何がどう違うのか聞きたくても・・・・

無念。ぷしゅう。

勉強するか。



f

リンク

2007/7/27(Fri) 17:19:58|NO.9809

GetFST()は、0.0しか帰ってこないみたいですな。
GetDST()でfloatでもdoubleでも受け取れるようなので問題ないですが。

自分に理解できればなあ(笑

テストに使ったコード
C側
float WINAPI testf(double data)
{ return ((float)data); } double WINAPI testd(double data) { return (data); } INT WINAPI testpd(double *outdata ,double indata) { *outdata = indata; return 0; }
HSP側
#uselib "test.dll"
#func Testf "testf" double #func Testd "testd" double #func Testpd "testpd" var , double data = 123.456789 : gosub *compute data = 987654.321 : gosub *compute data = 123456789.012345 : gosub *compute stop *compute mes "Base :" + data Testf data : getdata = GetFST() : mes "Float :" + getdata Testd data : getdata = GetDST() : mes "Double :" + getdata Testpd getdata, data : mes "Pointer:" + getdata mes "" return

結果
Base :123.456789
Float :0.000000
Double :123.456789
Pointer:123.456789

Base :987654.321000
Float :0.000000
Double :987654.321000
Pointer:987654.321000

Base :123456789.012345
Float :0.000000
Double :123456789.012345
Pointer:123456789.012345



Shinya

リンク

2007/7/27(Fri) 17:24:38|NO.9810

>GetFST()は、0.0しか帰ってこないみたいですな。
>GetDST()でfloatでもdoubleでも受け取れるようなので問題ないですが。
GetFSTはfloat型でそのまま返しているので、mesでは見れなくなっています。
どうしても、float型のままで扱いたいとき意外は保留ということでお願いします。



f

リンク

2007/7/27(Fri) 17:31:33|NO.9813

なるほど。
	Testf data : getdata = GetDST() : mes "Float  :" + double(getdata)

としてみたら、確かに中身が入っておりました。 精度もfloatでした(笑



YOYO

リンク

2007/7/27(Fri) 23:41:35|NO.9826

>7-9byteめの C20400(LE) は自前でスタックを戻すコードですが、個人的にはc3としたいです
callfunc()は元々WIN32APIを呼び出すためのものだと思ったのでstdcallにしました。
cdeclに比べてちょっとだけサイズが大きくなるけど、ほとんど変わらないと思います。
callfunc()のソース見たら両方に対応してましたのでどっちでも問題ないと思います。



おにたま(管理人)

リンク

2007/12/24(Mon) 16:20:56|NO.12894

SPAM防止のため、これ以降の返信を禁止させて頂きます。



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