goo

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 )