Форум: "Прочее";
Текущий архив: 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
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2007.09.23;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.055 c