Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2007.09.23;
Скачать: [xml.tar.bz2];

Вниз

Про компилятор   Найти похожие ветки 

 
_Mike_   (2007-08-10 17:31) [0]

Доброго времени суток!

Тут где-то тема была про Delphi компилятор. Ну вот вам пример.

const
 DEVICE_ADDRESS_LENGTH  = 6;
 DEVICE_CLASS_LENGTH    = 3;
 MAX_DEVICE_NAME_LENGTH = 64;

 BTSTATUS_FAIL                 = $00000000;

type
 PBLUETOOTH_DEVICE_INFO_EX = ^BLUETOOTH_DEVICE_INFO_EX;
 BLUETOOTH_DEVICE_INFO_EX = record
   dwSize:          DWORD;
   address:         array [0..DEVICE_ADDRESS_LENGTH - 1] of Byte;
   classOfDevice:   array [0..DEVICE_CLASS_LENGTH - 1] of Byte;
   szName:          array [0..MAX_DEVICE_NAME_LENGTH - 1] of Char;
   bPaired:         BOOL;
   ucLmpVersion:    UCHAR;
   wManuName:       Word;
   wLmpSubversion:  Word;
   reserved:        array [0..15] of Byte;
   wClockOffset:    Word;
   bConnected:      BOOL;
   dwDataRecvBytes: DWORD;
   dwDataSentBytes: DWORD;
   cSignalStrength: Char;
 end;

 PBT_GetLocalDeviceInfo     = function (dwMask: DWORD; var pDevInfo: BLUETOOTH_DEVICE_INFO_EX): DWORD; cdecl;

var
 _BT_GetLocalDeviceInfo:     PBT_GetLocalDeviceInfo     = nil;

function BT_GetLocalDeviceInfo(dwMask: DWORD; var pDevInfo: BLUETOOTH_DEVICE_INFO_EX): DWORD;
begin
 if Assigned(_BT_GetLocalDeviceInfo) then
   Result := _BT_GetLocalDeviceInfo(dwMask, pDevInfo)

 else
   Result := BTSTATUS_FAIL;
end;

function TBFBluetoothRadio.GetName: string;
var
 hRadio: THandle;
 BSInfo: BLUETOOTH_DEVICE_INFO_EX;
 MSInfo: BLUETOOTH_RADIO_INFO;
begin
 { TODO : Get Name }
 case FAPI of
   baBlueSoleil: begin
                   FillChar(BSInfo, SizeOf(BSInfo), 0);
                   BSInfo.dwSize := SizeOf(BSInfo);

                   if BT_GetLocalDeviceInfo(MASK_DEVICE_NAME, BSInfo) = BTSTATUS_SUCCESS then Result := string(BSInfo.szName);
                 end;

   baMicrosoft: begin
                     end;
                end;
 end;
end;


Внимание вопрос!

При выходе из функции AV.

Все параметры 100% верные.


 
oldman ©   (2007-08-10 17:42) [1]

А можно тоже самое, но нормально?
Я такого кривого кода давно не видел!!!


 
boa_kaa ©   (2007-08-10 17:47) [2]

Два вопроса:
1) в какой функции?
2) F7 & F8 сломаны?


 
MBo ©   (2007-08-10 17:52) [3]

>BLUETOOTH_DEVICE_INFO_EX = record
не packed record?

PBT_GetLocalDeviceInfo   - cdecl - это точно?

ошибка не с работой со строками связана?


 
tesseract ©   (2007-08-10 17:54) [4]


> Я такого кривого кода давно не видел!!!


ага, там явно PackedRecord. а BOOL там случайно не интом быть дожен ?


 
_Mike_   (2007-08-10 17:55) [5]


> MBo ©   (10.08.07 17:52) [3]


не packed, 100% cdecl, е со строками. Вот это работает:

procedure TBFBluetoothDiscovery.EnumRadiosBlueSoleil(Radios: TBFBluetoothRadios);
var
 Info: BLUETOOTH_DEVICE_INFO_EX;
 Radio: TBFBluetoothRadio;
 Addr: BLUETOOTH_ADDRESS;
begin
 FillChar(Info, SizeOf(Info), 0);
 Info.dwSize := SizeOf(Info);

 if BT_GetLocalDeviceInfo(MASK_DEVICE_ADDRESS, Info) = BTSTATUS_SUCCESS then begin
   Radio := TBFBluetoothRadio.Create;

   CopyMemory(@Addr.rgBytes[0], @Info.address[0], 6);

   with Radio do begin
     FAddress := BluetoothAddressToString(Addr.ullLong);
     FAPI := baBlueSoleil;
   end;

   Radios.FList.Add(Radio);
 end;
end;


В том же модуле. (MASK_DEVICE_NAME и MASK_DEVICE_ADDRESS на падение после GetName не влияют)

Подсказка - херится стек в _BT_GetLocalDeviceInfo (при вызове из GetName)


 
_Mike_   (2007-08-10 17:56) [6]


> ага, там явно PackedRecord. а BOOL там случайно не интом
> быть дожен ?

Не пакед. BOOL = DWORD = LongInt = Cardinal


 
_Mike_   (2007-08-10 17:59) [7]


> А можно тоже самое, но нормально?


Привидите пример кода, соответствующего Вашим высоким стандартам - я переформатирую.


> Я такого кривого кода давно не видел!!!

Я не просил комментировать оформление кусков кода вырезанные из разных модулей. Однако их более чем достаточно для того, чтобы вышеуказанное скомпилять.


> boa_kaa ©   (10.08.07 17:47) [2]
> Два вопроса:
> 1) в какой функции?
> 2) F7 & F8 сломаны?


Два ответа:
1) GetName.
2) Для Вас - да.


 
Rouse_ ©   (2007-08-10 18:02) [8]


> не packed, 100% cdecl,

А откедаль ты данную функцию берешь? irprops.cpl не экспортирует такого чуда, а то, что экспортирует - все сплош STDCALL


 
_Mike_   (2007-08-10 18:07) [9]


> Rouse_ ©   (10.08.07 18:02) [8]

BlueSoleil SDK


 
_Mike_   (2007-08-10 18:11) [10]

#ifdef __cplusplus
extern "C" {
#endif

#define BTEXPORT

#define DEVICE_ADDRESS_LENGTH   6
#define DEVICE_CLASS_LENGTH   3
#define MAX_DEVICE_NAME_LENGTH   64

#define BTSTATUS_SUCCESS   0x00000001

typedef struct _BLUETOOTH_DEVICE_INFO_EX {
DWORD dwSize;
BYTE address[DEVICE_ADDRESS_LENGTH];
BYTE classOfDevice[DEVICE_CLASS_LENGTH];
CHAR szName[MAX_DEVICE_NAME_LENGTH];
BOOL bPaired;
UCHAR ucLmpVersion;
WORD wManuName;
WORD wLmpSubversion;
BYTE reserved[16];
WORD wClockOffset;
BOOL bConnected;
DWORD dwDataRecvBytes;
DWORD dwDataSentBytes;
CHAR cSignalStrength;
} BLUETOOTH_DEVICE_INFO_EX, *PBLUETOOTH_DEVICE_INFO_EX;

BTEXPORT DWORD BT_GetLocalDeviceInfo (
       /* [in] */ DWORD dwMask,
       /* [out] */ PBLUETOOTH_DEVICE_INFO_EX pDevInfo
       );


 
tesseract ©   (2007-08-10 18:31) [11]


> Не пакед. BOOL = DWORD = LongInt = Cardinal


как не packed  у тебя там WORD!!!!! в с++ все записи упакованы по умолчанию. да и явно там STDCALL, в С++ он по умолчанию такой __cdecl не вижу я в функции.


 
Rouse_ ©   (2007-08-10 18:47) [12]

Хм... в сях выравнивание по умолчанию включено... а стек плывет бо CDECL дергает add.


 
_Mike_   (2007-08-10 18:51) [13]


> в с++ все записи


> #ifdef __cplusplus
> extern "C" {
> #endif



> Rouse_ ©   (10.08.07 18:47) [12]

Лучше поверьте - что там cdecl и нет выравнивания - это установлено 100%


 
_Mike_   (2007-08-10 18:54) [14]

Код из [5] работает. Грабля именно в GetName.
Да и в другом коде все также и работает.


 
_Mike_   (2007-08-10 18:59) [15]

По спец заказам - дабы убедить вас и убедиться еще раз самому - написал packed + stdcall - результат - вываливается раньше (в EnumRadios) так как соответствнно и параметры и вызов не верен.


 
Rouse_ ©   (2007-08-10 22:06) [16]


> Лучше поверьте - что там cdecl и нет выравнивания - это
> установлено 100%

Есть возможность выложить проект в том варианте, где четко детектируется ошибка? Я не могу выступать в роли отладчика, читая код с экрана :)
Если есть возможность - то оригинальные VC++ исходники демки приветствуются...


 
_Mike_   (2007-08-10 22:17) [17]


> Есть возможность выложить проект в том варианте, где четко
> детектируется ошибка?

Ошибка четко детектируется в функции GetName. Проект можете взять на сайте, а по поводу cdecl и packed/не packed - тут есть у человека сырцы - может подтвердить что оно cdecl и ну packed. И даже работает.

К сожалению - проект я выложить не могу по той причине, что проект коммерческий.

Код выше полность компилируемый (за исключением лишнего end в case который я не удалил (не заметил)). Достаточно его поместить в любой юнит и вызвать GetName.

максимум, что могу добавить:

hLib := LoadLibrary("btfunc.dll");

_BT_GetLocalDeviceInfo     := GetProcAddress(hLib, "BT_GetLocalDeviceInfo");


P.S. Тема была создана в основном в ответ на тему про компилятор, которая здесь проскакивала, а где мне популярно объяснили что я ламер... Ну вот вам задачка из тойже серии. Когда дельфевый компилятор падает на ровном месте и создает огромное количество гемороя для разработчика.


 
tesseract ©   (2007-08-10 22:38) [18]


>  Когда дельфевый компилятор падает на ровном месте и создает
> огромное количество гемороя для разработчика.


Ессно Delphi всегда имел проблемы с "отражением" памяти на структуры, а драйверы часто так пишуться.

> Хм... в сях выравнивание по умолчанию включено... а стек
> плывет бо CDECL дергает add.


Возможно, я в сях не очень, в EVC там выравнивание я не заметил - добивалось вручную Reserved, возможно проблема API от производителя данного девайса.  


>     if BT_GetLocalDeviceInfo(MASK_DEVICE_NAME, BSInfo) =
> BTSTATUS_SUCCESS then Result := string(BSInfo.szName);


гм, что то подсказывает, что  возможны проблемы как раз с прямым  приведением к string, у тебя szName запросто исчезнет при выходе из функции.

ЗЫ: Я уже пью пиво :-)


 
Servelat ©   (2007-08-10 23:01) [19]

> Когда дельфевый компилятор падает на ровном месте и создает
> огромное количество гемороя для разработчика.


Стало интересно. Не поленился запустить делфи.


> Код выше полность компилируемый


Не знаю как у Вас, а у меня делфи не знает ни что такое BLUETOOTH_RADIO_INFO ни что за FAPI который Вы case (ни даже что за класс TBFBluetoothRadio). Конструктивный разговор возможен когда вы выложите конкретный _компилирующийся_ пример, а иначе все всегда можно списать на ошибку в 17 строке.

Когда я был молод и юн, и только поступил в университет, а с делфи был знаком понаслышке, в одном проекте ловил AV при вызове виртуальной функции своего класса. Полчаса отлаживал (и материл компилятор, разработчиков и Гейтса), пока не обнаружил, что в одном месте попутал индексы и вышел за границу массива, чем испортил указатель на экземпляр объекта. Это к слову, как ошибка в одном месте может вызывать падение программы совсем в другом.

У меня нет сомнений в том, что делфевый компилятор неидеален. Однако "падает на ровном месте" это явно не про него. За все время пока я с ним работаю, у меня небыло к нему нареканий. Был разок обнаружен "небезопасный код" в VCL, много раз были ошибки из-за собственных кривых рук, но компилятор всегда был на высоте. Хотя не так давно была ветка про передачу динамического массива пустому конструктору, ну что ж, и на Солнце бывают пятна ;)

PS

> Проект можете взять на сайте,

Настолько же информативно как "рыбу обычно можно поймать в воде" или "вода, как правило, кипит при 100? С при нормальном атмосферном давлении".

PPS
 Заменив все неизвестные константы нулями либо единицами, и изменив функцию до следующего вида:

function BT_GetLocalDeviceInfo(dwMask: DWORD; var pDevInfo: BLUETOOTH_DEVICE_INFO_EX): DWORD;
begin
 Result := 1;
 pDevInfo.szName := "test";
end;


вызов GetName ошибки не "детектирует".


 
tesseract ©   (2007-08-10 23:12) [20]


> Не знаю как у Вас, а у меня делфи не знает ни что такое
> BLUETOOTH_RADIO_INFO ни что за FAPI который Вы case (


Не паясничай, ясно, что переводить заголовки API  к одной из самых распространённых программ для соединия с BlueTooth никто не захочет.

Кстати интересен сам  факт объявления указателя на структуру и передачи его в функцию по ссылке - что несколько разные вещи, может надо как раз указатель в функцию передавать? с выделенной под него памятью.

> var  _BT_GetLocalDeviceInfo:     PBT_GetLocalDeviceInfo
>     = nil;

Тут не засёк выделения,  глобальный переменные и так автообнуляються.

и тут не засёк выделения:

>  _BT_GetLocalDeviceInfo(dwMask, pDevInfo)


 
oxffff ©   (2007-08-10 23:35) [21]

Вот пример. cdecl нормально работает.

  PBT_GetLocalDeviceInfo= function (dwMask: DWORD; var pDevInfo: BLUETOOTH_DEVICE_INFO_EX): DWORD; cdecl;

var
 Form1: TForm1;

implementation

{$R *.dfm}
function Myfunc(dwMask: DWORD; var pDevInfo: BLUETOOTH_DEVICE_INFO_EX): DWORD; cdecl;
begin
//Do someThing
pDevInfo.szName:="All works properly";
result:=0;
end;

var FuncUnknown:PBT_GetLocalDeviceInfo=Myfunc;

function callFunc(dwMask: DWORD; var pDevInfo: BLUETOOTH_DEVICE_INFO_EX ):DWORD;
begin
result:=FuncUnknown(dwmask,pDevInfo);
end;

function abc:string;
var BSInfo:BLUETOOTH_DEVICE_INFO_EX;
begin
FillChar(BSInfo, SizeOf(BSInfo), 0);
BSInfo.dwSize := SizeOf(BSInfo);
callFunc(10,BSInfo);
result:=string(BSInfo.szName);
result:=BSInfo.szName;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(abc);
end;


 
Rouse_ ©   (2007-08-10 23:39) [22]


> Проект можете взять на сайте, а по поводу cdecl и packed/не
> packed - тут есть у человека сырцы - может подтвердить что
> оно cdecl и ну packed.

Я программист - а следовательно очень ленивый человек. Мне лень искать в ваших словах подтекст с урлом сайта, более того нет никакого желания доверять сломанному телефону в виде человека, который может подтвердить это подтвердить, темболее словами ну packed. Если есть компилируемый пример - тогда здраствуйте, если нет - тогда увы, но до свидания... Тратить свое время, не сбор данных для решения не моей "проблемы" я не намерен...
Отсюда нужно делать выводы...


 
_Mike_   (2007-08-10 23:42) [23]


> tesseract ©   (10.08.07 23:12) [20]

Отправил мылом полный проект. Падает в AV при GetName (запускаем демку - видим результат).

Тоже самое работает в EnumRadios.

Для запуска и отлова глюка - BlueSoleil1,6 или 2.3 (скачать можно здесь: http://www.btframework.com/support.htm)

P.S. Сюда просьба не постить то что отправил - того что я запостил здесь - более чем достаточно.


 
_Mike_   (2007-08-10 23:43) [24]


> Rouse_ ©   (10.08.07 23:39) [22]

Я где-то просил решить проблему????? Перечитайте внимательно всю ветку.


 
_Mike_   (2007-08-10 23:44) [25]


> tesseract ©   (10.08.07 23:12) [20]

Вторым письмо ушла ссылка на предыдущую версию где аналогичный код работает без AV.


 
_Mike_   (2007-08-10 23:49) [26]


> Кстати интересен сам  факт объявления указателя на структуру
> и передачи его в функцию по ссылке - что несколько разные
> вещи, может надо как раз указатель в функцию передавать?
>  с выделенной под него памятью.

var параметрв и передача указателя - синонимы. Т.е. при var передается фактически указатель.

Если оттрасирровать стек то все вроде бы ничего, пока не входим в _BT_GetLocalInfo. И вот тут начинаются чудеса.
Хз что дельфя там генерит на стеке, но функция затирает адрес возврата и херит часть полей структуры. Однако! Имя она вс=таки заполняет. Однакоже ни один регистр или что-то еще не страают в итоге. У меня такое ощущение что проблема с тем по границе какого адреса Delphi размещает параметры в стеке. (ща попробую AllocateMemory заюзать для структуры).

С другой стороны не понятно почему тот же вызов работает в EnumRadios.....


 
oxffff ©   (2007-08-10 23:55) [27]


> Подсказка - херится стек в _BT_GetLocalDeviceInfo (при вызове
> из GetName)


А что под отладчиком нельзя посмотреть?.

Вот вызов вашей функции

1:
push @pDevInfo
push dwMask
call [_BT_GetLocalDeviceInfo]
add esp,8; //это точно cdecl вызов
2:

Где валится?  Как конкретно стек затирается?


 
oxffff ©   (2007-08-11 00:00) [28]


> Хз что дельфя там генерит на стеке, но функция затирает
> адрес возврата и херит часть полей структуры


Ай да чудеса.
А слабо посмотреть размер структуры в С++ и сравнить ее с BSInfo.dwSize?


 
_Mike_   (2007-08-11 00:09) [29]


> А слабо посмотреть размер структуры в С++ и сравнить ее
> с BSInfo.dwSize

Конечно. Я же дебил, до такого догадаться не мог без Вашего совета.


 
oxffff ©   (2007-08-11 00:11) [30]


> Конечно. Я же дебил, до такого догадаться не мог без Вашего
> совета.


Да вы зря обижаетесь.
Если вы говорите, про перетирание адреса возврата, то явно что-то не в порядке.
Вы лучше скажите какой адрес перетирается

Адрес возврата в BT_GetLocalDeviceInfo?


 
_Mike_   (2007-08-11 00:13) [31]


> oxffff ©   (11.08.07 00:11) [30]

Если размер структуры не валидны - функция вернет INVALID_ARGUMENT.

Сейчас попробую отловить место где киляется адрес возврата (я уже 3 день воюю с этой херней)


 
oxffff ©   (2007-08-11 00:13) [32]

Или Адрес возврата в GetName?


 
oxffff ©   (2007-08-11 00:19) [33]

А попробуйте сделать так.

function TBFBluetoothRadio.GetName: string;
var
hRadio: THandle;
PBSInfo: PBLUETOOTH_DEVICE_INFO_EX;
begin
{ TODO : Get Name }
case FAPI of
  baBlueSoleil: begin
                   new(PBSInfo);
                    zeromemory(PBSInfo,sizeof(BLUETOOTH_DEVICE_INFO_EX));
                     PBSInfo^.dwSize := SizeOf(BLUETOOTH_DEVICE_INFO_EX);
                    if BT_GetLocalDeviceInfo(MASK_DEVICE_NAME, PBSInfo^) = BTSTATUS_SUCCESS then Result := PBSInfo^.szName;
                   dispose(PBSInfo);
                  end;

end;
end;

Перетирание должно убраться.
А если нет, то тем еще хуже.


 
_Mike_   (2007-08-11 00:19) [34]

Итак:

0012F300 - 0047c425 - адрес возврата из _BT_GetLocalInfo (из DLL)
0012F304 - 00000001 - MASK_NAME
0012F308 - 0012F534 - адрес структуры (в стеке естественно)

0012F534 - начало структуры
0012F5AC - последний DWORD структуры
0012F5В0 - 0012F5E4 - указатель стека на что-то (сохранен при вызове GetName)
0012F5B4 - 00481533 - адрес возврата из GetName

после вызова _BT_GetLocalInfo перед возвратом из GetName (когда уже эпилог прошел перед ret)
0012F5В0 - 00000000 - указатель стека на что-то (сохранен при вызове GetName)
0012F5B4 - 00000000 - адрес возврата из GetName


 
_Mike_   (2007-08-11 00:20) [35]


> oxffff ©   (11.08.07 00:19) [33]

Делал - один хер. Только в другом адресе AV вылетает (так AV 0/0, а если выделять память - то с другими циферками :)


 
oxffff ©   (2007-08-11 00:22) [36]

Если перетирание адреса возврата не уберется, то значит проблема в логике
external процедуры. А если да , значит проблема скорее всего как в несоответствии структур и так в возможно логике.
Идею вы надеюсь поняли. Пусть уж лучше кучу перетирает.


 
_Mike_   (2007-08-11 00:23) [37]

Посмотрел EnumRadios - такого поведения не наблюдается - т.е. дело не в _BF_GetLocalInfo (хотя я уже хер знает что и думать).


 
_Mike_   (2007-08-11 00:25) [38]


> oxffff ©   (11.08.07 00:22) [36]

Я уверен что не в функции. Потому как этот код работает в предыдущей версии. Он там точно такой же (за исключением того, что GetName вынесена отдельной процедурой)
Но! Даже если я добавляю в GetName флаги, которые используются в пердыдущей версии (т.е. копирую код полностью) - ничего не меняется - все также сыпется.


 
oxffff ©   (2007-08-11 00:27) [39]


> _Mike_   (11.08.07 00:19) [34]


См. [27]

Ты лучше скажи значение esp до вызова call [_BT_GetLocalDeviceInfo] и до ret из процедуры. Надеюсь там не ret 8.


 
_Mike_   (2007-08-11 00:30) [40]


> oxffff ©   (11.08.07 00:27) [39]

Я это [27] третьи сутки наблюдаю...

Как положено - 0012F304

нет. там не ret 8


 
oxffff ©   (2007-08-11 00:36) [41]


> Как положено - 0012F304
>
> нет. там не ret 8


Так не положено. См [34]

Адрес возврата  0012F300


 
oxffff ©   (2007-08-11 00:39) [42]

Все проблемы в DLL


 
_Mike_   (2007-08-11 00:43) [43]


> Адрес возврата  0012F300

Он там и будет ПОСЛЕ входа в процедуру а не

> до вызова call [_BT_GetLocalDeviceInfo]



> Все проблемы в DLL

Нету там проблемы.... В этом все горе....


 
_Mike_   (2007-08-11 00:48) [44]


> Все проблемы в DLL

Проблемма в том, как дельфя выравняла структуру. Она должна была ее выровнять до 132 (длина) а выровняла до 124.


 
oxffff ©   (2007-08-11 00:49) [45]


> _Mike_   (11.08.07 00:43) [43]
>
> > Адрес возврата  0012F300
>
> Он там и будет ПОСЛЕ входа в процедуру а не
>
> > до вызова call [_BT_GetLocalDeviceInfo]


Приведи код вызова и значение ESP перед вызовом(т.е на  call, но не после него) . и Далее esp на ret но не после ret

Инструкции вызова и 5 последних инструкций возврата


 
oxffff ©   (2007-08-11 01:01) [46]


> Она должна была ее выровнять до 132 (длина) а выровняла
> до 124.


Скажите сколько физически занимает структура в С++?


 
oxffff ©   (2007-08-11 01:02) [47]

Я опять повторяю вопрос из [28].
Желаю другой ответ, а не [29]


 
oxffff ©   (2007-08-11 01:09) [48]

>Проблемма в том, как дельфя выравняла структуру. Она должна была ее >выровнять до 132 (длина) а выровняла до 124.

Если структура занимает физически в С++ 132. А в Delphi 124. То это две разные структуры. Соотвествие полей нет.


 
oxffff ©   (2007-08-11 01:13) [49]

У вас есть как минимум хороший шанс перетереть адрес переданной структуры и адрес возврата из BT_GetLocalDeviceInfo.

Кстати это проблемы не Delphi. Это проблемы С++. ;)

Проблемы вы создали сами.

Ничего бывает.

Все спокойной ночи.


 
Германн ©   (2007-08-11 01:14) [50]


> Проблемма в том, как дельфя выравняла структуру. Она должна
> была ее выровнять до 132 (длина) а выровняла до 124.
>

Что значит "должна была"?
124 получится в случае packed record или {$A-}, {$A1}.
132 получится с случае {$A4}.
А какие опции компилятора в твоём проекте?


 
_Mike_   (2007-08-11 01:37) [51]


> Если структура занимает физически в С++ 132

124 она в C (еще раз - нету там C++)


 
_Mike_   (2007-08-11 01:38) [52]


> 124 получится в случае packed record или {$A-}, {$A1}.

117

> 132 получится с случае {$A4}.
> А какие опции компилятора в твоём проекте?

124
по умолчанию (A8)


 
Германн ©   (2007-08-11 01:56) [53]


> _Mike_   (11.08.07 01:38) [52]
>
>

Наверно у меня другая арифметика :)


 
Германн ©   (2007-08-11 02:30) [54]


> _Mike_   (11.08.07 01:38) [52]
>
>

Да, кстати. При
> по умолчанию (A8)
структура она же запись
> BLUETOOTH_DEVICE_INFO_EX = record
>    dwSize:          DWORD; 8
>    address:         array [0..DEVICE_ADDRESS_LENGTH - 1]
> of Byte; +8=16
>    classOfDevice:   array [0..DEVICE_CLASS_LENGTH - 1] of
> Byte; +8=24
>    szName:          array [0..MAX_DEVICE_NAME_LENGTH - 1]
> of Char; +64=88
>    bPaired:         BOOL; +8=96
>    ucLmpVersion:    UCHAR; +8=104
>    wManuName:       Word; +8=112
>    wLmpSubversion:  Word; +8=120
>    reserved:        array [0..15] of Byte; +16=136
>    wClockOffset:    Word; +8=144
>    bConnected:      BOOL; +8=152
>    dwDataRecvBytes: DWORD; +8=160
>    dwDataSentBytes: DWORD; +8=168
>    cSignalStrength: Char; +8=176
>  end;
>

должна была бы занять в памяти 172 байта.


 
Германн ©   (2007-08-11 03:11) [55]


> Германн ©   (11.08.07 02:30) [54]
>
>

Очепятка.
176 байт ессно!


 
_Mike_   (2007-08-11 09:54) [56]


> Германн ©   (11.08.07 03:11) [55]

Я не буду чего-то доказывать - я вижу что считает дельфи.
при A4 и A8 - 124
при packed = 117 (что очень просто пощитать сложением). Может вы в восьмеричной считаете - бог Вас знаете.
Но IMHO прежде чем что-то утверждать е поленитесь запустить дельфи, вставить туда объявление структуры и написать SizeOf - Вы будете удивлены.

P.S. A8, A4 - не размер, выделяемый каждому элементу, а граница, по которой будет выравниваться структура (long/long long).

P.P.S. Простейщая программка, написанная за 3 минуты - покажет Вам смещение полей структуры тносительно ее начала.


 
oxffff ©   (2007-08-11 11:39) [57]


> _Mike_   (11.08.07 09:54) [56]


Я тебе еще раз вопрос задаю. Сколько занимает физически (в памяти) структура  на С и на Delphi (Сколько показывает Sizeof там и там)?


 
isasa ©   (2007-08-11 11:48) [58]

:)
124
Причем с А4 и А8 (в D7).
Как вариант "выровнять" ручками до 132.


 
Anatoly Podgoretsky ©   (2007-08-11 14:27) [59]

> isasa  (11.08.2007 11:48:58)  [58]

Какое то бардачное обсуждение со стороны автора, правда соответствует конференции.


 
isasa ©   (2007-08-11 14:50) [60]

Anatoly Podgoretsky ©   (11.08.07 14:27) [59]
Там действительно по опции $A8 в полях Word не происходит выравнивания на 8 байт. В структуре отведено 4. Видно в окошке CPU - распределение памяти(нижнее, GoToAddress).
С этой фигней я сталкивался еще когда надо было перетянуть старые ст-ры из под TP5 в Delphi. Пришлось искать Tp и писать конвертер в нем. :)
Но это не было большой трагедией.


 
isasa ©   (2007-08-11 14:51) [61]

Да, вышесказанное относится к D7.


 
Anatoly Podgoretsky ©   (2007-08-11 15:44) [62]

> isasa  (11.08.2007 14:50:00)  [60]

Но хотя бы включить проверку границ не помешает.


 
_Mike_   (2007-08-12 00:17) [63]


> Я тебе еще раз вопрос задаю. Сколько занимает физически
> (в памяти) структура  на С и на Delphi (Сколько показывает
> Sizeof там и там)?

Я уже раз 10 написал размеры структур и в сях и в дельфе.


> Какое то бардачное обсуждение со стороны автора, правда
> соответствует конференции.

И что там бардачного???


> Да, вышесказанное относится к D7.

И D6 и прочим.


> Но хотя бы включить проверку границ не помешает.

Смысл?


 
Piter ©   (2007-08-12 00:44) [64]

_Mike_   (12.08.07 0:17) [63]
Я уже раз 10 написал размеры структур и в сях и в дельфе


все таки ты бы мог еще раз написать четко, сколько показывает Sizeof и там, и там. Просто два числа, без ошибок. Не думаю, что это сложно.


 
oxffff ©   (2007-08-12 10:41) [65]


> _Mike_   (12.08.07 00:17) [63]
>
> > Я тебе еще раз вопрос задаю. Сколько занимает физически
>
> > (в памяти) структура  на С и на Delphi (Сколько показывает
>
> > Sizeof там и там)?
>
> Я уже раз 10 написал размеры структур и в сях и в дельфе.
>


Я уже который раз повторяю, что если у тебя структура в delphi занимает 124 байта (c учетом выравнивания), то что sizeof возвращает.
А в external процедуре занимает 132 байта (c учетом выравнивания), то
перезатирание адреса возврата и одного из переданных параметров (а именно адреса структуры) гарантировано, если между ними "нет других переменных".

Тебе уже сказали выравнивай структуры в ручную.

Читай [28] и свой ответ [29].

Cтек

Адрес1:  {
            BLUETOOTH_DEVICE_INFO_EX  124 байта
            }
            адрес возврата в Getname
            Адрес1 (var Параметр pDevInfo);
            dwMask;
            адрес возврата в BT_GetLocalDeviceInfo

Если ты перетираешь адрес возврата в Getname это одно.
А если Адрес1 перетираешь (фактически локальный параметр из external процедуры ), то функция может вообще перетирать во произвольному адресу все что хочешь.
Все это делает твоя external процедура.

Надеюсь ты опять не понял.
Буду рад в очередной раз написать тебе тоже самое.


 
oxffff ©   (2007-08-12 10:47) [66]


> Надеюсь ты опять не понял.
> Буду рад в очередной раз написать тебе тоже самое.


Если не понял, не беда.
Я постараюсь тебе подробнее написать с примером.


 
Stijn   (2007-08-23 17:09) [67]

Hi, I"m trying to use btfunc.dll with Delphi also, but I get 2 (BTSTATUS_SYSTEM_ERROR) from BT_GetLocalDeviceInfo for some strange reason. I tried "packed record" also, but doesn"t help. Strange. BT_InitializeLibrary, BT_IsBlueSoleilStarted and BT_GetVersion work though.

Did you find any solution?



Страницы: 1 2 вся ветка

Форум: "Прочее";
Текущий архив: 2007.09.23;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.65 MB
Время: 0.041 c
15-1188267803
ArtemESC
2007-08-28 06:23
2007.09.23
Ночью перечитал Евгения Онегина...


8-1166262763
niko
2006-12-16 12:52
2007.09.23
Загрузка BitMap а и вывод его на форму в Си


15-1187863283
самовар
2007-08-23 14:01
2007.09.23
Вопрос по php


11-1170931264
Dodfr
2007-02-08 13:41
2007.09.23
Problem with Vista


2-1188551855
Gloomer
2007-08-31 13:17
2007.09.23
Как узнать ошибку по значению GetLastError





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский