全然更新しないブログ
HSPメモ帳
HSP3x64
環境
os: Windows10 x64 __hspver__: 0x3507
64ビット アプリケーションの作成
デフォルトでは32bitアプリが作成されますが、ランタイムをhsp3_64にすることで64bitアプリを作成することができます。
詳細は、Helpで#runtime を参照。
#runtime "hsp3_64" dialog "64bit",, "HSP3_64" stop
注意点
現在、64bitランタイムはβテスト版です。64ビット整数が扱えないので関連する命令等は使用できません。
詳細は、プログラミング・マニュアル(hspprog.htm)の2.25. 64bit(x64)対応版ランタイムの利用について を参照。
mod_x64
正式版がでるまでの代替モジュール mod_x64を作成。
64ビット整数の代わりとして、doubleを使用。
- x64(p1, p2)
- 64ビット値の作成 p1は下位32ビット値、p2は上位32ビット値。 戻り値はdouble型の64ビット値。
- x64varptr(p1)
- 変数p1のポインタ取得。戻り値はdouble。
- x64func p1, p2, p3, p4, p5
- 関数呼び出し用の変数を作成。 p1はDLL名、p2は関数名。p3は関数の引数の数、p4は、関数の戻り値が整数の場合0、doubleの場合1を指定。 p5は、関数呼び出し用配列変数を指定。 戻り値は成功1、失敗0。
- x64call(p1, p2)
- 関数呼び出し。 p1はx64funcで作成した変数(p5)、p2は引数用のdouble型配列。 戻り値は関数の戻り値(double型)。
- x64dcall(p1, p2, p3, ...)
- define定義の関数呼び出し。 p1は、x64funcかx64methodで作成した変数、 x64funcの場合、p2から引数を指定。 x64methodの場合、p2はx64newcomで作成した変数(p3)、p3から引数を指定。 p17まで指定可能。 戻り値は関数、メソッドの戻り値(double型)。
- x64newcom p1, p2, p3
- COMオブジェクトの作成。 p1はCLSID文字列、p2は、IID文字列、p3は、COMオブジェクト用変数。 戻り値は成功1、失敗0。
- x64method p1, p2, p3, p4, p5
- メソッド呼び出し用の変数を作成。 p1は、x64newcomで作成した変数(p3)、p2は、メソッドindex値、p3は、メソッドの引数の数、p4は、関数の戻り値が整数の場合0、doubleの場合1を指定。 p5は、メソッド呼び出し用配列変数を指定。 戻り値は成功1、失敗0。
- x64ccall(p1, p2, p3)
- メソッド呼び出し。 p1はx64methodで作成した変数(p5)、p2は、x64newcomで作成した変数(p3)。 p3は、引数用のdouble型配列。 戻り値はメソッドの戻り値(double型)。
- x64query p1, p2, p3
- QueryInterface呼び出し。 p1は、x64newcomで作成した変数(p3)、p2は、IID文字列、p3は、COMオブジェクト用変数。 戻り値はHRESULT。
- x64release p1
- Release呼び出し。 p1は、x64newcomで作成した変数(p3)。 戻り値はリファレンスカウント。
- x64proc p1
- ウィンドウプロシージャの変更。 HWND, uMsg, wParam, lParamを取得できるようにします。 p1は、プロシージャ用の変数(実数型配列)。 HWNDは、p1(0) または、x64proc_hwnd(p1)。 uMsgは、p1(1) または、x64proc_msg(p1)。 wParamは、p1(2) または、x64proc_wp(p1)。 lParamは、p1(3) または、x64proc_lp(p1)。 戻り値は無し。
サンプル 関数呼び出し
#include "mod_x64.hsp" x64func "kernel32.dll", "GetCommandLineA", 0, 0, dGetCommandLineA x64func "kernel32.dll", "lstrcpyA", 2, 0, dlstrcpyA ddim dArgs, 4 dRet = 0.0 sdim dst, 1024 dRet = x64call(dGetCommandLineA, dArgs) dArgs = x64varptr(dst), dRet dRet = x64call(dlstrcpyA, dArgs) mes strf("GetCommandLine: [%s]", dst) stop
サンプル wParamの取得
#include "mod_x64.hsp" x64func "shell32.dll", "DragAcceptFiles", 2, 0, dDragAcceptFiles x64func "shell32.dll", "DragQueryFileA", 4, 0, dDragQueryFileA x64func "shell32.dll", "DragFinish", 1, 0, dDragFinish #define global ctype DragAcceptFiles(%1, %2) x64dcall(dDragAcceptFiles, %1, %2) #define global ctype DragQueryFileA(%1, %2, %3, %4) x64dcall(dDragQueryFileA, %1, %2, %3, %4) #define global ctype DragFinish(%1) x64dcall(dDragFinish, %1) #define global WM_DROPFILES 0x0233 sdim mb, 1024 screen 0 mesbox mb, ginfo_winx, ginfo_winy x64proc proc oncmd gosub *DropFiles, WM_DROPFILES dRet = DragAcceptFiles(x64(hwnd, 0), x64(1, 0)) stop *DropFiles // if ( x64low(x64proc_msg(proc)) != WM_DROPFILES ){ return } buf = "" hDrop = x64proc_wp(proc) dRet = DragQueryFileA(hDrop, x64(-1, -1), x64(0, 0), x64(0, 0)) n = x64low(dRet) sdim fileName, 260 repeat n dRet = DragQueryFileA(hDrop, x64(cnt, 0), x64varptr(fileName), x64(260, 0)) buf += fileName + "\n" loop dRet = DragFinish(hDrop) title strf("ファイル数 %d", n) objprm 0, buf return
サンプル COMオブジェクト
#include "mod_x64.hsp" x64func "kernel32.dll", "lstrcpyW", 2, 0, dlstrcpyW x64func "Oleaut32.dll", "SysAllocString", 1, 0, dSysAllocString x64func "Oleaut32.dll", "SysReAllocString", 2, 0, dSysReAllocString x64func "Oleaut32.dll", "SysFreeString", 1, 0, dSysFreeString #define global CLSID_DOMDocument30 "{f5078f32-c551-11d3-89b9-0000f81fe221}" #define global IID_IXMLDOMDocument "{2933BF81-7B36-11d2-B20E-00C04F983E60}" bufXml = {"<html> <body> <div id='id1'>hsp2</div> <div id='id2'>hsp3</div> </body> </html>"} mes strf("dXmlDoc.loadXML({¥"%s¥"})¥n", bufXml) sdim wBufXml, 1024 ddim args, 4 dRet = 0.0 : dRet2 = 0.0 : dNode = 0.0 dBstr = 0.0 : dBstr2 = 0.0 x64newcom CLSID_DOMDocument30, IID_IXMLDOMDocument, dXmlDoc x64method dXmlDoc, 37, 2, 0, selectSingleNode x64method dXmlDoc, 65, 2, 0, loadXML sdim wBufXml, (strlen(bufXml) + 1) * 2 cnvstow wBufXml, bufXml dBstr = x64dcall(dSysAllocString, x64varptr(wBufXml)) dRet = x64dcall(loadXML, dXmlDoc, dBstr, x64varptr(dRet2)) xpath = "//div[@id='id2']" cnvstow wBufXml, xpath dRet = x64dcall(dSysReAllocString, x64varptr(dBstr), x64varptr(wBufXml)) dRet = x64dcall(selectSingleNode, dXmlDoc, dBstr, x64varptr(dNode)) x64method dNode, 26, 1, 0, get_text dRet = x64dcall(get_text, dNode, x64varptr(dBstr2)) dRet = x64dcall(dlstrcpyW, x64varptr(wBufXml), dBstr2) mes strf("dXmlDoc.selectSingleNode(¥"%s¥").get_text(): [%s]", xpath, cnvwtos(wBufXml)) dRet = x64dcall(dSysFreeString, dBstr2) dRet = x64dcall(dSysFreeString, dBstr) x64release dNode x64release dXmlDoc stop
mod_x64.hsp
#ifndef MOD_X64_HSP_ #define global MOD_X64_HSP_ #include "hsp3_64.as" #define global ctype x64dcall(%1, %2 = 0, %3 = 0, %4 = 0, ¥ %5 = 0, %6 = 0, %7 = 0, %8 = 0, %9 = 0, %10 = 0, %11 = 0, ¥ %12 = 0, %13 = 0, %14 = 0, %15 = 0, %16 = 0, %17 = 0) ¥ x64dcall_(%1, %2, %3, %4, %5, %6, %7, %8, %9, ¥ %10, %11, %12, %13, %14, %15, %16, %17) #define global ctype x64proc_hwnd(%1) %1(0) #define global ctype x64proc_msg(%1) %1(1) #define global ctype x64proc_wp(%1) %1(2) #define global ctype x64proc_lp(%1) %1(3) #module mod_x64 #define X64_Call LoadModule_ #define X64_CallName "LoadModule" #uselib "user32.dll" #func wsprintfA_ "wsprintfA" var,str,var #func SetWindowLongPtrW_ "SetWindowLongPtrW" int,int,double #uselib "kernel32.dll" #func X64_Call X64_CallName int,var,var,var #func GetModuleHandle_ "GetModuleHandleA" double #func LoadLibrary_ "LoadLibraryA" double #func GetProcAddress_ "GetProcAddress" double,double #func RtlMoveMemory_ "RtlMoveMemory" double,double,int #func VirtualProtect_ "VirtualProtect" var,int,int,var #func lstrcmp_ "lstrcmpA" double,double #deffunc x64err str errMsg dialog "Error: " + errMsg, , "mod_x64" end return #deffunc x64init d = 0.0 : d2 = 0.0 ddim dArgs, 8 ddim dRet, 2 if ( 0 ){ x64_Call 0, d, d2, ret LoadLibrary_ 0 GetProcAddress_ 0, 0 } GetModuleHandle_ x64(0, 0) if ( stat == 0x400000 ){ x64err "Not 64bit runntime" } if ( x64funcst(X64_CallName, 4, 0, d, d2) == 0 ){ x64err X64_CallName } dim code, 40 code(0) = $244C894C, $8B485508, $D28548EC, $8B486B74, $C0854802, $C9856374, $854D3D74, $485A74C0 code(8) = $E2C1D18B, $20EA8303, $DAF7047D, $E28303EB, $E22B4808, $41C9FF48, $7FC834FF, $415A59F7 code(16) = $66594158, $C16E0F48, $6E0F4866, $0F4966CA, $4966D06E, $48D96E0F, $FF20EC83, $8B48C9D0 code(24) = $4808244C, $0974C985, $66018948, $417E0F48, $C0C74808, $00000001, $C03348C3, $0000C3C9 VirtualProtect_ code, 40 * 4, 0x40, i1 dCode = x64varptr(code) x64copy x64move(d2, 24), x64varptr(dCode), 8 dim codeProc, 20 codeProc(0) = $aaaab848, $aaaaaaaa, $8948aaaa, $48082444, $a348c18b, $bbbbbbbb, $bbbbbbbb, $cca3c28b codeProc(8) = $cccccccc, $49cccccc, $a348c08b, $dddddddd, $dddddddd, $48c18b49, $eeeeeea3, $eeeeeeee codeProc(16) = $448b48ee, $ff480824, $000000e0 buf = "LoadLibraryA" if ( x64funcst(buf, 1, 0, dLoad, d) == 0 ){ x64err buf } buf = "GetProcAddress" if ( x64funcst(buf, 2, 0, dProc, d) == 0 ){ x64err buf } buf = "IIDFromString" x64func "ole32.dll", buf, 2, 0, dIidStr if ( stat == 0 ){ x64err buf } buf = "CoCreateInstance" x64func "ole32.dll", buf, 5, 0, dCoInst if ( stat == 0 ){ x64err buf } x64func "user32.dll", "GetWindowLongPtrW", 2, 0, dGetWindowLongPtrW return #defcfunc x64 int lp, int hp dMake = 0.0 lpoke dMake, 0, lp lpoke dMake, 4, hp return dMake #defcfunc x64zero double src dSrc = src if ( lpeek(dSrc, 0) == 0 && lpeek(dSrc, 4) == 0 ){ return 1 } return 0 #defcfunc x64low double src dSrc = src return lpeek(dSrc, 0) #defcfunc x64high double src dSrc = src return lpeek(dSrc, 4) #defcfunc x64varptr var v bufV = "" wsprintfA_ bufV, "%p", v l = strlen(bufV) if ( l > 8 ){ i1 = int("$"+strmid(bufV, -1, 8)) i2 = int("$"+strmid(bufV, 0, l - 8)) } else { i1 = int("$"+strmid(bufV, 0, l)) i2 = 0 } return x64(i1, i2) #defcfunc x64move double src, int nPos if ( nPos == 0 ){ return src } dSrc = src i1 = lpeek(dSrc, 0) i2 = lpeek(dSrc, 4) i = i1 + nPos if ( nPos > 0 ){ if ( i1 < 0 && i > 0 ) { i2++ } } else { if ( i1 > 0 && i < 0 ){ i2-- } } i1 = i return x64(i1, i2) #deffunc x64copy double dst, double src, int nSize if ( nSize <= 0 ){ return 0 } RtlMoveMemory_ dst, src, nSize return nSize #defcfunc x64funcst str funcName, int len, int bRetd, array dFunc, var dstdat ret = 0 if ( ctx == 0 ){ mref ctx, 68 dHed = x64(ctx(0), ctx(1)) dim aHed, 28 x64copy x64varptr(aHed), dHed, 112 dFInfo = x64(ctx(342), ctx(343)) dMds = x64(ctx(6), ctx(7)) dim stdat, 10 } name = funcName dName = x64varptr(name) repeat aHed(15) / 40 x64copy x64varptr(stdat), x64move(dFInfo, cnt * 40), 40 if ( wpeek(stdat, 2) == 0xfffc ){ lstrcmp_ dName, x64move(dMds, stdat(3)) if ( stat == 0 ){ ddim dFunc, 3 dFunc = x64(stdat(6), stdat(7)), x64(len, 0) if ( bRetd ){ dFunc(2) = 1.0 } dstdat = x64move(dFInfo, cnt * 40) ret = 1 break } } loop return ret #deffunc x64func str libName, str funcName, int len, int bRetd, array dFunc ddim dFunc, 3 dFunc(1) = x64(len, 0) if ( bRetd ){ dFunc(2) = 1.0 } buf = libName dArgs = x64varptr(buf) dLib = x64call(dLoad, dArgs) if ( x64zero(dLib) != 0 ){ return 0 } buf = funcName dArgs = dLib, x64varptr(buf) dCall = x64call(dProc, dArgs) if ( x64zero(dCall) != 0 ){ return 0 } dFunc(0) = dCall return 1 #defcfunc x64dcall_ array dFunc, ¥ double p1, double p2, double p3, double p4, ¥ double p5, double p6, double p7, double p8, ¥ double p9, double p10, double p11, double p12, ¥ double p13, double p14, double p15, double p16 i1 = lpeek(dFunc, 8) if ( i1 > 16 ){ return x64(0, 0) } ddim dcallArgs, 16 if ( i1 > 0 ){ dcallArgs(0) = p1, p2, p3, p4, p5 } if ( i1 > 5 ){ dcallArgs(5) = p6, p7, p8, p9, p10 } if ( i1 > 10 ){ dcallArgs(10) = p11, p12, p13, p14, p15, p16 } x64_Call i1, dFunc, dcallArgs, dRet if ( dFunc(2) == 1.0 ){ return dRet(1) } return dRet(0) #defcfunc x64call array dFunc, array aArgs i1 = lpeek(dFunc, 8) if ( i1 > length(aArgs) ){ return x64(0, 0) } x64_Call i1, dFunc, aArgs, dRet if ( dFunc(2) == 1.0 ){ return dRet(1) } return dRet(0) #defcfunc x64iidstr str iid, array aIid i1 = strlen(iid) sdim wStrIid, (i1 + 1) * 2 cnvstow wStrIid, iid dim aIid, 4 dArgs = x64varptr(wStrIid), x64varptr(aIid) d = x64call(dIidStr, dArgs) if ( x64zero(d) == 0 ){ return 0 } return 1 #deffunc x64newcom str classid, str iid, var dCom if ( x64iidstr(classid, aIid1) == 0 ){ return 0 } if ( x64iidstr(iid, aIid2) == 0 ){ return 0 } dCom = x64(0, 0) dArgs = x64varptr(aIid1), x64(0, 0), x64(15, 0), x64varptr(aIid2), x64varptr(dCom) d = x64call(dCoInst, dArgs) if ( x64zero(d) == 0 ){ return 0 } return 1 #deffunc x64method double dCom, int cID, int len, int bRetd, array dMethod if ( x64zero(dCom) ){ return 0 } ddim dMethod, 3 ddim dVT, 1 x64copy x64varptr(dVT), dCom, 8 if ( x64zero(dVT) ){ return 0 } x64copy x64varptr(dMethod), x64move(dVT, cID * 8), 8 dMethod(1) = x64(len + 1, 0) if ( bRetd ){ dMethod(2) = 1.0 } return 1 #defcfunc x64ccall array dMethod, double dCom, array aArgs i1 = lpeek(dMethod, 8) ddim dcArgs, i1 dcArgs(0) = dCom repeat i1 - 1 : dcArgs(cnt + 1) = aArgs(cnt) : loop return x64call(dMethod, dcArgs) #deffunc x64query double dCom, str iid, var dComq x64method dCom, 0, 2, 0, dQuery if ( stat == 0 ){ return 0 } if ( x64iidstr(iid, aIid1) == 0 ){ return 0 } ddim queryArgs, 2 ddim dComq, 1 queryArgs = x64varptr(aIid1), x64varptr(dComq) return x64ccall(dQuery, dCom, queryArgs) #deffunc x64release double dCom x64method dCom, 2, 0, 0, aRelease if ( stat == 0 ){ return 0 } return x64ccall(aRelease, dCom, dRet) #deffunc x64proc array procInfo // procInfo(0): hWnd procInfo(1): uMsg // procInfo(2): wParam procInfo(3): lParam ddim procInfo, 16 repeat 19 lpoke procInfo, cnt * 4 + 48, codeProc(cnt) loop dRet = x64varptr(procInfo(0)) lpoke procInfo, 68, lpeek(dRet, 0) : lpoke procInfo, 72, lpeek(dRet, 4) dRet = x64varptr(procInfo(1)) lpoke procInfo, 79, lpeek(dRet, 0) : lpoke procInfo, 83, lpeek(dRet, 4) dRet = x64varptr(procInfo(2)) lpoke procInfo, 92, lpeek(dRet, 0) : lpoke procInfo, 96, lpeek(dRet, 4) dRet = x64varptr(procInfo(3)) lpoke procInfo, 105, lpeek(dRet, 0) : lpoke procInfo, 109, lpeek(dRet, 4) dArgs = x64(hwnd, 0), x64(-4, 0) dRet = x64call(dGetWindowLongPtrW, dArgs) lpoke procInfo, 50, lpeek(dRet, 0) : lpoke procInfo, 54, lpeek(dRet, 4) VirtualProtect_ procInfo, 16 * 8, 0x40, i1 SetWindowLongPtrW_ hwnd, -4, x64varptr(procInfo(6)) return #global x64init #endif // MOD_X64_HSP_
コメント ( 0 ) | Trackback ( 0 )