Всем привет. 1) приведение типов. AFAIK размер смещения указателей в Си, в отличие от Ассемблера, происходит от типа указателя. То-есть Код (Text): (long*)pointer+1 приведёт к смещению на DWORD. Но если мне нужно смещение в байтах, а результат long. Писал для этого: Код (Text): *(long*)((char*)pointer+1) Но как-то монструозно и искусственно. Может можно проще? 2)О стандартах. У Borland и Microsoft, активно применяются типы DWORD, BYTE и тд. Но у меня gcc такого не понимает. А применять long, int не хотелось бы, так как их размер варьируется от машины и компилятора. З.Ы. Сильно не пинайте, в сях не очень силён.
1) используй unsigned char* pointer например 2) посмотри определения в WinDef.h. Кто мешает использовать их в gcc?
IceStudent Спасибо, втупил по полной. Но что это означает, что unsigned long всегда будет DWORD?. Таким образом что, тип приведётся автоматически, с извлечением DWORD данных? Что-то не пойму. Можно пример.
нет, это DWORD всегда будет unsigned long (32бита) 1) указатель будет на однобайтовые данные, будет как в асме арифметика. если нужно будет извлечь 4 байта, то потребуется приведение: DWORD d = *((DWORD*)pointer);
обычно в системных бтблиотеках присутствует хедер с определениями типов конкретных размеров, у M$ это BYTE, WORD, DWORD; в GNU libc -- uint8_t, int16_t и тп. Надо просто поискать. а насчёт инкремента указателя, я бы сделал так: union { char *pc; long *pointer; }; ... pc ++; printf ("%ld", *pointer);
А как насчёт обычного макро-расширения? И на его базе более узкоспециальные макросы: Код (Text): #define PTR_MOVE(p,type,bytes) (type*)(((unsigned char*)(p))+(bytes)) #define PLONG_MOVE(p,bytes) PTR_MOVE(p,long,bytes) #define PLONG_MOVE_ME(p,bytes) p=PLONG_MOVE(p,bytes) long* p = ...; p = PLONG_MOVE (p, 5); // Move it 5 bytes forward PLONG_MOVE_ME (p, -3); // Move it 3 bytes back PLONG_MOVE_ME (p, sizeof (int)); // Кросс-платформенно даже!
AsmGuru62 Отличная идея! В winnt.h есть несколько макросов (FIELD_OFFSET, RTL_CONTAINS_FIELD, CONTAINING_RECORD, RTL_NUMBER_OF), выполняющих подобные задачи, но именно такого нет.
>>А применять long, int не хотелось бы long и подорузомевает long int ) ибо по умолчанию если тип не определяешь то он int... киньте в меня кирпичем если я не прав.. но по стандарту так должно быть long int и long - одно и тоже...
AsmGuru62 Спасибо за макросы. rgo Да, но хотелось бы пользоваться единым стандартом типов, ведь называют же Си портируемым ассемблером.. И насчёт размера типов, разве оговаривается, что long всегда 4 байта. Если в стандарте это указано, тогда не прав. Но я вседа думал, что это зависит от конкретного компилятора. Ведь есть версии где int - 16 бит, а есть где 32. И не известно как это будет дальше. А если нужно всегда работать именно с определённым размером данных, не зависимо от платформы и компилятора? Или всегда придётся шаманить с хедерами?
Нет. Указано только то, что я привёл выше. Тогда переопределять типы на __intN или uintN_t, или что-то ещё, в зависимости от компилятора, и использовать переопределённые, типа BYTE или uint8.
Кстати обнаружил дикий глю в BC5 (тот что можно на шару скачать) - определяю BYTE как usigned char а работает с ним он как с signed (везде повставлял movsx собака)... Убил неделю пока понял в чем дело...
не нужно использовать драные компиляторы на шару много чего скачать дают, а msvs 2005 присылают по почте (4 DVD)