|
#1
|
||||
|
||||
Приведение типов
В Дельфи
Код:
function myproc(user : Pointer) : QWORD; stdcall; begin Result := TMyClass(user).field.field; end; Код:
unsigned long long WINAPI myproc(void *user) { CMyClass *pMyClass = (CMyClass *) user; return = pMyClass->field.field; } Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#2
|
||||
|
||||
Как вариант еще и так можно:
Код:
(foo as TObject).Bar Ты в х64 бабахаешь (судя по QWORD)? — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение: | ||
angvelem (15.05.2013)
|
#3
|
||||
|
||||
Не прокатывает.
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#4
|
||||
|
||||
Можно
Код:
unsigned long long WINAPI myproc(void *user) { return ((CMyClass *)user)->field; } jmp $ ; Happy End! The Cake Is A Lie. |
Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
angvelem (15.05.2013)
|
#5
|
||||
|
||||
Это был мой первый вариант написания, с него и началась свистопляска с компилятором. Ну не хочет он его воспринимать.
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#6
|
||||
|
||||
Только обратил внимание. Привычка Дельфиста писать = (после return), хотя одна ошибка ушла, но поле класса недоступно.
Чёрт бы побрал этот С (на ассемблер было легче переписать). В данном случае он не видит поля, пока они находятся в секции private. Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. Последний раз редактировалось angvelem, 15.05.2013 в 01:02. |
#7
|
||||
|
||||
Код:
function proc_read(buffer : Pointer; length : DWORD; user : Pointer) : DWORD; stdcall; begin with MyClass(user).field do begin if (field1 >= 0) and (length >= 0) then begin Result := field2 - field1; if Result > 0 then begin if Result > length then Result := length; Move(Pointer(Longint(field3) + field1)^, buffer^, Result); inc(field1, Result); Exit; end; end; end; Result := 0; end; Код:
unsigned long WINAPI proc_read(void *buffer, unsigned long length, void *user) { CMyClass *pMyClass = (CMyClass *)user; if (pMyClass->field.field1 >= 0 && length >= 0) { unsigned long i = (pMyClass->field.field2 - pMyClass->field.field1); if (i > 0) { if (i > length) i = length; memmove(buffer, (pMyClass->field.field3 + pMyClass->field.field1), i); pMyClass->field.field1 += i; return i; } } return 0; } Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#8
|
||||
|
||||
Не знаю, каких типов field3 и field1, но судя по тому, как используется выше - int. Тогда должно сработать так:
Код:
memmove(buffer, (void *)(pMyClass->field.field3 + pMyClass->field.field1), i); jmp $ ; Happy End! The Cake Is A Lie. |
Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
angvelem (15.05.2013)
|
#9
|
||||
|
||||
Структура такая
Код:
struct Cfield { void *field3; unsigned long long field2; unsigned long long field1; }; Так получаю предупреждение на подозрительную арифметику Код:
memmove(buffer, (void *)((int *)(pBassPlayer->SoundData.Data) + pBassPlayer->SoundData.Seek), i); Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. Последний раз редактировалось angvelem, 15.05.2013 в 02:13. |
#10
|
||||
|
||||
А, ну тогда да. void * - вообще штука темная.
Код:
memmove(buffer, ((char *)pMyClass->field.field3 + pMyClass->field.field1), i); jmp $ ; Happy End! The Cake Is A Lie. |
Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
angvelem (15.05.2013)
|
#11
|
||||
|
||||
Предупреждение остаётся.
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#12
|
||||
|
||||
Оно и будет оставаться, однако размер char - 1 байт. Возможно исчезнет предупреждение если сделать так
Код:
memmove(buffer, (void *)((unsigned long long)pMyClass->field.field3 + pMyClass->field.field1), i); Код:
memmove(buffer, &((char *)pMyClass->field.field3)[pMyClass->field.field1], i); jmp $ ; Happy End! The Cake Is A Lie. |
Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
angvelem (15.05.2013)
|
#13
|
||||
|
||||
Первый вариант компилятор полностью устроил, не вякает больше.
Осталось устранить последнюю ошибку. Код:
extern void WINAPI proc_close(void *user); extern unsigned long long WINAPI proc_length(void *user); extern unsigned long WINAPI proc_read(void *buffer, unsigned long length, void *user); extern bool WINAPI proc_seek(unsigned long long offset, void *user); ... BASSProcs.close = proc_close; BASSProcs.length = proc_length; BASSProcs.read = proc_read; BASSProcs.seek = proc_seek; // Здесь кака Цитата:
Код:
// User file stream callback functions typedef void (CALLBACK FILECLOSEPROC)(void *user); typedef QWORD (CALLBACK FILELENPROC)(void *user); typedef DWORD (CALLBACK FILEREADPROC)(void *buffer, DWORD length, void *user); typedef BOOL (CALLBACK FILESEEKPROC)(QWORD offset, void *user); typedef struct { FILECLOSEPROC *close; FILELENPROC *length; FILEREADPROC *read; FILESEEKPROC *seek; } BASS_FILEPROCS; Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. Последний раз редактировалось angvelem, 15.05.2013 в 02:37. |
#14
|
||||
|
||||
Только при компиляции под х32 приведение указателя к unsigned long long будет обсчитывать лишние 4 байта, которые всегда будут нули. Так что не универсально.
Как-то так: Код:
void *a = (void *)0x12345678; volatile unsigned long long b = (unsigned long long)a; ... mov ecx, 12345678h mov eax, ecx xor edx, edx mov [ebp+var_8], eax mov [ebp+var_4], edx jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 15.05.2013 в 02:40. |
#15
|
||||
|
||||
Изменил на unsigned long компилятор промолчал. При отладке видно будет, так или нет.
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |