![]() |
|
|
#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;
} |
|
#2
|
||||
|
||||
|
Как вариант еще и так можно:
Код:
(foo as TObject).Bar Ты в х64 бабахаешь (судя по QWORD)? |
| Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение: | ||
angvelem (15.05.2013)
| ||
|
#3
|
||||
|
||||
|
Не прокатывает.
![]() |
|
#4
|
||||
|
||||
|
Можно
Код:
unsigned long long WINAPI myproc(void *user)
{
return ((CMyClass *)user)->field;
} |
| Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
angvelem (15.05.2013)
| ||
|
#5
|
||||
|
||||
|
Это был мой первый вариант написания, с него и началась свистопляска с компилятором. Ну не хочет он его воспринимать.
|
|
#6
|
||||
|
||||
|
Только обратил внимание. Привычка Дельфиста писать = (после return), хотя одна ошибка ушла, но поле класса недоступно.
Чёрт бы побрал этот С (на ассемблер было легче переписать). В данном случае он не видит поля, пока они находятся в секции private. Последний раз редактировалось 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;
} |
|
#8
|
||||
|
||||
|
Не знаю, каких типов field3 и field1, но судя по тому, как используется выше - int. Тогда должно сработать так:
Код:
memmove(buffer, (void *)(pMyClass->field.field3 + pMyClass->field.field1), i); |
| Этот пользователь сказал Спасибо 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); Последний раз редактировалось angvelem, 15.05.2013 в 02:13. |
|
#10
|
||||
|
||||
|
А, ну тогда да. void * - вообще штука темная.
Код:
memmove(buffer, ((char *)pMyClass->field.field3 + pMyClass->field.field1), i); |
| Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
angvelem (15.05.2013)
| ||
|
#11
|
||||
|
||||
|
Предупреждение остаётся.
![]() |
|
#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); |
| Этот пользователь сказал Спасибо 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;Последний раз редактировалось 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 Последний раз редактировалось Bargest, 15.05.2013 в 02:40. |
|
#15
|
||||
|
||||
|
Изменил на unsigned long компилятор промолчал. При отладке видно будет, так или нет.
|