Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > C/C++ > C++ Builder
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 14.05.2013, 13:56
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию Приведение типов

В Дельфи
Код:
function myproc(user : Pointer) : QWORD; stdcall;
begin
  Result := TMyClass(user).field.field;
end;
в C
Код:
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  
Старый 14.05.2013, 14:10
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Как вариант еще и так можно:
Код:
(foo as TObject).Bar

Ты в х64 бабахаешь (судя по QWORD)?
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение:
angvelem (15.05.2013)
  #3  
Старый 14.05.2013, 14:16
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Не прокатывает.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #4  
Старый 14.05.2013, 18:39
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Можно
Код:
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  
Старый 15.05.2013, 00:13
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Это был мой первый вариант написания, с него и началась свистопляска с компилятором. Ну не хочет он его воспринимать.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #6  
Старый 15.05.2013, 00:31
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Только обратил внимание. Привычка Дельфиста писать = (после return), хотя одна ошибка ушла, но поле класса недоступно.

Чёрт бы побрал этот С (на ассемблер было легче переписать). В данном случае он не видит поля, пока они находятся в секции private.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.

Последний раз редактировалось angvelem, 15.05.2013 в 01:02.
Ответить с цитированием
  #7  
Старый 15.05.2013, 01:59
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Код:
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;
}
Bargest, посмотри что не так с memmove.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #8  
Старый 15.05.2013, 02:05
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Не знаю, каких типов 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  
Старый 15.05.2013, 02:09
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Структура такая
Код:
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  
Старый 15.05.2013, 02:15
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

А, ну тогда да. void * - вообще штука темная.
Код:
memmove(buffer, ((char *)pMyClass->field.field3 + pMyClass->field.field1), i);
Можно и unsigned char. Не помню точно, но вроде как в сях сложение с указателем прибавляет по размеру того, на что указатель. То есть int *a = (int*)b + 1 физически переведется в b + 4. Ну а что такое void он знать не знает.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
angvelem (15.05.2013)
  #11  
Старый 15.05.2013, 02:22
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Предупреждение остаётся.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #12  
Старый 15.05.2013, 02:26
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Оно и будет оставаться, однако размер 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  
Старый 15.05.2013, 02:30
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Первый вариант компилятор полностью устроил, не вякает больше.

Осталось устранить последнюю ошибку.
Код:
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; // Здесь кака
Цитата:
Cannot convert 'bool (__stdcall *)(unsigned __int64,void *)' to 'int (__stdcall *)(unsigned __int64,void *)' in function CMyClass::LoadSound(const char *)
Хотя по-описанию
Код:
// 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;
она возвращает bool
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.

Последний раз редактировалось angvelem, 15.05.2013 в 02:37.
Ответить с цитированием
  #14  
Старый 15.05.2013, 02:33
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Только при компиляции под х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  
Старый 15.05.2013, 02:40
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Изменил на unsigned long компилятор промолчал. При отладке видно будет, так или нет.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 11:10.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter