Тема: AHK: как получить адрес переменной внутри класса
Вопрос в заголовке.
Допустим, возьмем какой-нибудь мессенджер. Будет в нем некий класс "обработчик сообщений" (_msgprocessor). Он инициализируется при запуске скрипта.
;start
processor:=new _msgprocessor
;предположим, что здесь идет цикл listen - он слушает порт,
;при получении пакета, обрабатывает его и в конце получает присланное сообщение
num:=439
msg:="Привет, мир!"
processor.new(num,msg) ;посылаем обработчику сообщение
;потом тут идет несколько проверок на целостность пакета, не затерялась ли информация
;и только потом сообщение записывается в файл
processor.set()
return
class _msgprocessor {
static data, size
new(num, msg) {
this.data:="#" num " - " msg "`n"
this.size:=StrLen(this.data) * A_IsUnicode?2:1
}
set() {
H:=File_Open("Write", A_Desktop "\list.bin")
File_Write(H, &this.data, this.size) ;ну и здесь не работает, т.к. &this.data = ничему
File_Close(H)
}
}
CopyBinData(ptrSource, ptrDestination, iLength) {
If iLength ;Only do it if there's anything to copy
DllCall("RtlMoveMemory", "Ptr", ptrDestination, "Ptr", ptrSource, "UInt", iLength)
}
/*! TheGood
Simple file functions
http://www.autohotkey.com/forum/viewtopic.php?t=56510
*/
File_Open(sType, sFile) {
bRead := InStr(sType, "READ")
bSeq := sType = "READSEQ"
;Open the file for writing with GENERIC_WRITE/GENERIC_READ, NO SHARING/FILE_SHARE_READ & FILE_SHARE_WRITE, and
;OPEN_ALWAYS/OPEN_EXISTING, and FILE_FLAG_SEQUENTIAL_SCAN
hFile := DllCall("CreateFile", "Str", sFile, "UInt", bRead ? 0x80000000 : 0x40000000, "UInt", bRead ? 3 : 0, "Ptr", 0
, "UInt", bRead ? 3 : 4, "UInt", bSeq ? 0x08000000 : 0, "Ptr", 0, "Ptr")
If (hFile = -1 Or ErrorLevel) { ;Check for any error other than ERROR_FILE_EXISTS
ErrorLevel := ErrorLevel ? ErrorLevel : A_LastError
Return -1 ;Return INVALID_HANDLE_VALUE
} Else Return hFile
}
File_Read(hFile, ByRef bData, iLength = 0) {
;Check if we're reading up to the rest of the file
If Not iLength ;Set the length equal to the remaining part of the file
iLength := File_Size(hFile) - File_Pointer(hFile)
;Prep the variable
VarSetCapacity(bData, iLength, 0)
;Read the file
r := DllCall("ReadFile", "Ptr", hFile, "Ptr", &bData, "UInt", iLength, "UInt*", iLengthRead, "Ptr", 0)
If (Not r Or ErrorLevel) {
ErrorLevel := ErrorLevel ? ErrorLevel : A_LastError
Return -1
} Else Return iLengthRead
}
File_Write(hFile, ptrData, iLength) {
;Write to the file
r := DllCall("WriteFile", "Ptr", hFile, "Ptr", ptrData, "UInt", iLength, "UInt*", iLengthWritten, "Ptr", 0)
If (Not r Or ErrorLevel) {
ErrorLevel := ErrorLevel ? ErrorLevel : A_LastError
Return -1
} Else Return iLengthWritten
}
File_Pointer(hFile, iOffset = 0, iMethod = -1) {
;Check if we're on auto
If (iMethod = -1) {
;Check if we should use FILE_BEGIN, FILE_CURRENT, or FILE_END
If (iOffset = 0)
iMethod := 1 ;We're just retrieving the current pointer. FILE_CURRENT
Else If (iOffset > 0)
iMethod := 0 ;We're moving from the beginning. FILE_BEGIN
Else If (iOffset < 0)
iMethod := 2 ;We're moving from the end. FILE_END
} Else If iMethod Is Not Integer
iMethod := (iMethod = "BEGINNING" ? 0 : (iMethod = "CURRENT" ? 1 : (iMethod = "END" ? 2 : 0)))
r := DllCall("SetFilePointerEx", "Ptr", hFile, "Int64", iOffset, "Int64*", iNewPointer, "UInt", iMethod)
If (Not r Or ErrorLevel) {
ErrorLevel := ErrorLevel ? ErrorLevel : A_LastError
Return -1
} Else Return iNewPointer
}
File_Size(hFile) {
r := DllCall("GetFileSizeEx", "Ptr", hFile, "Int64*", iFileSize)
If (Not r Or ErrorLevel) {
ErrorLevel := ErrorLevel ? ErrorLevel : A_LastError
Return -1
} Else Return iFileSize
}
File_Close(hFile) {
If Not (r := DllCall("CloseHandle", "Ptr", hFile)) {
ErrorLevel := ErrorLevel ? ErrorLevel : A_LastError
Return False
} Return True
}