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


HSPTV!掲示板


未解決 解決 停止 削除要請

2015
0831
NoaHSP 3.5 beta 2の64ビットランタイム下でのポインタおよびAPIに引き渡される構造体の扱い24解決


Noa

リンク

2015/8/31(Mon) 15:00:01|NO.71162

ただの勘違いかもしれませんがどうしても分からないので質問します。
HSP 3.5 beta 2にて64ビットのランタイムを使用する場合、ポインタはどのように処理すればいいのでしょうか。
HSPでは64ビット整数は扱えないためかAPIの返し値でポインタが64ビットから32ビットにキャストさせられ桁落ちでポインタが正しい位置を指さなくなってしまい、アクセス時にエラーが出てしまいます。
double型や配列で代用しようかと思いましたがそもそもAPIが32ビット整数でしか返してくれませんでした。
そこでAPIで64ビット整数を受け取りそれをdupptrに渡す方法を教えてください。


メモリをGlobalAllocで確保して開放するスクリプト(問題の発生する一例)



#include "hsp3_64.as" #define GPTR $40//0で初期化された固定メモリ #uselib "kernel32.dll" #cfunc GlobalAlloc "GlobalAlloc" int,int #func GlobalFree "GlobalFree" int p=GlobalAlloc(GPTR,4) if p==0: dialog "メモリ確保に失敗" : end dupptr a,p,4 a=5 mes a GlobalFree p


問題を発生させる(たぶん)最小限のコード(varptrの64ビット変数への非対応による)



#include "hsp3_64.as" a=5 dupptr b,varptr(a),4//ここで桁落ち(dup b,aでは問題ない) mes b//ここで「動作を停止しました」が発生する


また構造体で64ビット単位で処理して計算速度をあげるために入れられる詰め物はHSPではどのような扱いになりますか。
下のスクリプトではHSPでは詰め物は使わないようにされているようにわたしはみえます。


RECT構造体を使用するスクリプト



#include "hsp3_64.as" #define SPI_GETWORKAREA $30 #uselib "user32.dll" #func SystemParametersInfo "SystemParametersInfoA" int,int,var,int dim rect,4 SystemParametersInfo SPI_GETWORKAREA,0,rect,0 tate=rect.3-rect.1 yoko=rect.2-rect.0 mes "タスクバーを除いたデスクトップの広さ" mes "横="+yoko+"\n縦="+tate memset rect,,16 mes "\n配列に詰め物はないことを確認するためRECT構造体代わりの配列を0で初期化\n" foreach rect mes "rect."+cnt+"="+rect.cnt loop



この記事に返信する


KA

リンク

2015/8/31(Mon) 18:01:57|NO.71172


・64bit(x64)版ランタイムについて 64bit(x64)アプリとして動作するHSP3標準ランタイム(hsp3_64.exe)を同梱しています。 使用する場合は、スクリプトの先頭に以下の行を指定してください。 #include "hsp3_64.as" 64bit(x64)ランタイムは、64bit版のWindows上でのみ動作します。 このバージョンは、将来の64bit化に向けてのテスト版とお考えください。 通常は、標準の32bit版HSP3ランタイム(hsp3.exe)をご使用頂いて問題ありません。 現状では、64bitランタイムに以下の注意点があります。 ・従来のHSPスクリプトを64bitアプリとして動作させるランタイムです  (整数値の範囲など従来の仕様が変わるものではありません) ・1つの変数が使用するメモリバッファは2GB(32bit)が上限となります  (スクリプト全体が使用できるメモリサイズは64bitアプリに準拠します) ・従来の32bit版プラグインとは互換性がありません ・COM関連の命令が正しく動作しないことがあります

単に64ビットアプリと認識されるだけで、仕様的には32ビットと同等と
考えた方が良いでしょう。



Noa

リンク

2015/8/31(Mon) 18:46:45|NO.71175

>仕様的には32ビットと同等

すみません。そのことは知っていましてその仕様的には32ビットと同等なことにこまっています。
スクリプトをHSP 3.5 beta 2で実行してみると分かると思いますが仕様的には32ビットと同じなのでvarptrなどが32ビットでしかポインタを返してくれず桁落ちが発生して正しくメモリーのアドレスを取得できないということです。
64ビット版を使わず32ビット版を使えばいいのですがどうにも気になるのです。
勘違いしていたらすみません。



Noa

リンク

2015/8/31(Mon) 19:07:20|NO.71176

ようするにlong long int型やできればULONG_PTR型(ポインタを格納できる符号なし整数)のようなものを使いたいのです。



kanamaru

リンク

2015/8/31(Mon) 22:39:24|NO.71185

longintやvarptrの結果を代入した整数型変数はどうでしょうか?
longintは検索すればでてきます。



おにたま

リンク

2015/8/31(Mon) 22:51:25|NO.71186

>Noa さん

x64版ランタイムについて貴重なご意見ありがとうございます。
ご指摘の通り、x64版ランタイムでHSP側の変数ポインタに正しく64bit値を設定する方法は今のところありません。
今後、32bitの時と同様にAPIを使っていくためには、どうしても64bitポインタを扱う必要が出てくるので、何らかの対応をしたいと考えています。
dupptrやvarptrを拡張して上位と下位32bitずつを個別に指定するような拡張をすればできないことはないですが、
あまりスマートとは言えないので、何か良い提案があれば参考にしたいと思っています。
整数(int)を64bitにするのも1つの手段ですが、かなりの変更になるため、新しい型を用意するか、doubleを代替として使用することも検討しています。



kanamaru

リンク

2015/8/31(Mon) 22:58:42|NO.71187

int32とint64といった風に変数型を分けるのもいいかもしれません。
従来のようにint型も使えるようにした上で、標準は32bitにし、
場合によって使い分けることでより多くの環境に対応出来ると思います。
自動でbitを切り替えるのもいいかも知れません。



Noa

リンク

2015/8/31(Mon) 23:34:35|NO.71190

>longintは検索すればでてきます。

blueleafさんのlongint.dllは32ビット用のDLLなので使えません。

押しつけがましいことですみませんができれば符号なし整数も扱えるようにしてほしいです。
符号なし整数はAPIの呼び出しに使う際に便利ですので。

そしておにたまさん、kanamaruさん、ありがとうございます。



Noa

リンク

2015/8/31(Mon) 23:37:28|NO.71191

ところで構造体の詰め物はどうなのでしょうか。
仕様は32ビットと同じなので詰め物はないということでいいのでしょうか。



tds12

リンク

2015/8/31(Mon) 23:56:32|NO.71192




Noa

リンク

2015/9/1(Tue) 02:12:10|NO.71195

リンク先をずっと見ていましたがちんぷんかんぷんでした。それでなんとなく理解できたことについて質問します。
HSPではHSPランタイム自体のコンパイル時にコンパイル時のオプションで詰め物が入らないようにしてあるということでいいのですか。
また詰め物がはいるかどうかは32ビットか64ビットかではなくコンパイル時のオプションで決められてそしてC言語コンパイラ標準のオプションがビットによって異なっている場合があり、配列のメンバーの配置が変化するということですか。
RECT構造体の場合はHSPランタイム自体のコンパイル時のオプションに影響せず詰め物は入らなそうですが、HSPでは詰め物のことは気にしなくていいのですか。
HSPでは構造体が使えず配列で代用するので詰め物が入るかどうかは大きいと思います。



Noa

リンク

2015/9/1(Tue) 02:23:28|NO.71196

書いていてよく分からなくなったのでまとめると、HSPでは詰め物の影響は受けないのか、APIに渡される構造体の各メンバーは一人ひとり連続してメモリ上に並んでいるものとして扱っていいのか、ということです。
もし詰め物の影響を受けるのならその対処法を知りたいです。



Noa

リンク

2015/9/1(Tue) 03:11:38|NO.71197

ところで掲示板の投稿欄でホームページのURLを記入するところがありますがURLが長すぎて途中で切れるのですがどうしたらいいのですか。
直接POSTで送信すれば送れるとは思いますがここのシステムはどのくらいの長さのURLに対応していますか。



skyblue

リンク

2015/9/1(Tue) 13:35:11|NO.71205

peek/pokeで構造体にあわせた読書きと言うのはどうですか?
パディングが無いならばpeek/pokeを使わずに同様に読書きをするとか

おにたまさんへ
64bit版のときだけプログラムの出力時に
ポインタなどの出力をふさわしいものにするという
ネイティブ64bit方式とかどうですか?
もしくは32bitと34bitで別のプログラムにするとか



Noa

リンク

2015/9/1(Tue) 16:46:59|NO.71210

>peek/pokeで構造体にあわせた読書き

ただ単に自分が理解できていないのでしょうがまさにそれが詰め物の配置関係が分からなければできないと思います。
http://chokuto.ifdef.jp/advanced/struct.html
ちょくとさんのこのページのように各メンバーがメモリ上に連続して並んでいるものとして64ビット版HSPランタイムでも取り扱っていいのかということです。
わたしは構造体のメンバーの名前を各メンバーの構造体のなかでの位置で定義して
sdim kouzoutai,1024
なにか処理
lpeek(kouzoutai.miso)
wpeek(kouzoutai.tofu)
のようにして使っています。

個人的にはポインタなどの出力が64ビットランタイムのときだけ変わるのはint型が64ビットでコンパイルしたかによって大きさが変化することになるのでややこしくなるのでいやです。
個人的にはなるべくそのままで動くように64ビット長整数を追加するか(つまりlongint.dllのlongintを標準で扱えるようにする)または配列かなにかで処理できるようにしてほしいです。



Noa

リンク

2015/9/1(Tue) 16:59:51|NO.71212

すみません。わたしが聞きたいのは
http://chokuto.ifdef.jp/advanced/struct.html
ちょくとさんのこのページの内容は64ビットのHSPランタイムでも通用するのかどうかということです。



Noa

リンク

2015/9/2(Wed) 16:13:54|NO.71257

ふと変数情報を直接見ればvarptrについては解決できるかもと思い書いてみましたが結局dupptrを使うのでだめでした。


#module /* varinfoka(tofu,0)=vartype(tofu) varinfoka(tofu,1)=varptr(tofu) にあたります */ #defcfunc varinfoka var p1, int p2, local hspctxstrr, local pvaladr, local pvala mref hspctxstrr,68 dupptr pvaladr,hspctxstrr.207,4 dupptr pvala,pvaladr,48,vartype("str") if p2==0 : return wpeek(pvala) if p2>=1 : return lpeek(pvala,28) return 0 #global #define MB_ICONINFORMATION $40 #define MB_OK 0 #uselib "user32.dll" #func MessageBox "MessageBoxA" int,int,int,int a="みそ" b="ちくわ" ap=varinfoka(a,1)//varptr(a) bp=varinfoka(b,1)//varptr(b) MessageBox hwnd,ap,bp,MB_ICONINFORMATION|MB_OK end



skyblue

リンク

2015/9/2(Wed) 16:16:41|NO.71258

最適化をかけていない場合はパディング無し
オプションでパディングのサイズを指定している場合はそのサイズ
指定していない場合は1,2,4,8バイトで切り上げされています。

そして64bitにかかわらずInt型のサイズは変わりません。(Long型は変わります)
なのでHSPの実装でIntかLongのどちらでしているかによります。

上記の理由からC/C++など他の言語の場合は
Int型を使っている限り気にしなくて大丈夫です。
bit数の非混合かつ同じOSで使っている限りは
Long型を使っていても他の言語を使っていれば大丈夫です。

補足するならWinである限りパディングはあまり気にしなくても大丈夫です。
理由は以前のスレに書いてある通り
すでにパディングする理由であるアライメントに考慮されて作られているからです。

ただし、戻り値が64bitポインタの場合は現在の所実行不可です。(HSPの場合)
および、64bitポインタの場合
それ以外の場合も2倍のサイズを確保しておけば大丈夫です。
その気になればすべての変数のサイズを8バイトとして計算すると言うのも
最低でもLongとポインタ、気分でIntを計算すれば大丈夫です。



Noa

リンク

2015/9/2(Wed) 16:31:32|NO.71259

skyblueさんありがとうございます。ようやく詰め物について理解できたかと思います。
確かにパディングについて確かめようとAPIで使う構造体をいろいろ見てみましたがどれも詰め物が入るようなようになっておらず(ただ単に見た数が少なすぎただけかもしれませんが)、
どうしてかと思っていましたが最初から考慮されてつくられていたのですか。
手持ちのプログラミングの本では64ビットについては概念のようなことだけでここまでは詳しく説明されていなく検索のしかたもわからずなやんでいました。
わかりやすく教えてくれてありがとうございます。変なことを書いていたらすみません。



zakki

リンク

2015/9/2(Wed) 21:59:06|NO.71273

細かいところですがWindowsはLLP64でlong longが64bitですね。
パディングはABIの一部なのでHSPでだろうがCだろうが影響受けますが
Windows APIで使う構造体に限ると大多数は気にする必要のないように定義されてるかと。



inovia

リンク

2015/9/2(Wed) 22:23:22|NO.71276

久々に早く帰れたので、
longintプラグインの64bit版ぽいのを作ってみました。
http://hsp.moe/download/hspint64_100.zip

int()
lpeek()
lpoke
varptr()
dupptr()
callfunc()

の64bit版が使えるようになります。



Noa

リンク

2015/9/3(Thu) 00:10:47|NO.71278

まさか自分の質問がここまで大きく広がるとは思いませんでした。下手の横好きでプログラミングをしているわたしの質問に答えてくれてありがとうございます。
またハンドルは32ビットしか使っていないということを初めて知りました。URL先を見て納得できました。

またもしinoviaさんがこの質問を見てくれていればできれば教えてほしいのですが、
HTMLのコメントの人物は改造版HSPスクリプトエディタの写真にあるキャラクターですか。またなぞの大量の33この<BR>はなぜですか。
特に意味はなかったりするのであればすみません。

inoviaさん、プラグインまでつくってくださりありがとうございます。
そして答えてくれたプログラマーのみなさん感謝します。



inovia

リンク

2015/9/3(Thu) 06:00:38|NO.71282

>HTMLのコメントの人物は改造版HSPスクリプトエディタの写真にあるキャラクター
ですです。プロ生ちゃんですね。

>またなぞの大量の33この<BR>はなぜですか。
Aタグのラベルジャンプ時に位置がずれるのを避けるため、BRで空間を開けています。
(特に4Kディスプレイ環境だとずれる)
あまりいい方法ではないんですけどね。

---

一応念のため。
ビルドはVisualStudio2013環境で行っているので、XPの64bit版では動かないと思います。
Vista以上であれば平気かと。



skyblue

リンク

2015/9/3(Thu) 07:31:33|NO.71283

>細かいところですがWindowsはLLP64でlong longが64bitですね。
正しくはLP64でLLP64ではない。
LP64はLongとポインタが64bitと言う意味です。
LLつまりLong Longは規格で64bitであることが決められているので関係ないです。



Noa

リンク

2015/9/3(Thu) 20:40:34|NO.71296

わざわざ答えてくださりすみません。聞こうにも掲示板はほぼ使われていないようでTwitterはこわくて使えないのでずっと聞けずにいました。また確かに<BR>がないとずれます。



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