Подскажите в чем проблема: есть прога на языке TurboС-3.0 с обработчиком прерывания от таймера (18 раз в секунду). По таймеру заполняется динамический список, в основной проге обрабатываются этот список. В WinXP все работало нормально, но возникла необходимость работать в DOS (системная дискета Win98), где этот же текст зависает (вроде бы на операторе new в обработчике прерывания, который или зависает или выдает NULL). Статический список не устраивает. В DOS прогу навсякий случай перекомпилил, не помогло. Упрощенный текст программы: Код (Text): #include <stdio.h> #include <dos.h> #include <conio.h> #ifdef __cplusplus #define __CPPARGS ... #else #define __CPPARGS #endif struct BuffList{ //buffer obmena unsigned int NumVK; struct BuffList *next; BuffList() {NumVK=0; next=NULL;} ~BuffList() {NumVK=0; next=NULL;} } start, *node, *first, *last, *ppp; int cnt = 0; void interrupt get_out(__CPPARGS); void interrupt (*oldfunc)(__CPPARGS); void main(void) { clrscr(); start.next = NULL; node = first = last= &start; oldfunc = _dos_getvect(0x1c); _disable(); _dos_setvect(0x1c,get_out); _enable(); delay(100); first=first->next; while (1) { if (first->next==NULL) continue; node=first; first=node->next; // здесь должна быть длительная обработка информации printf("drn",node->NumVK); delete node; } _disable(); _dos_setvect(0x1c,oldfunc); _enable(); } void interrupt get_out(__CPPARGS) // обработка прерывания от таймера 18 раз в сек. { if (cnt==256) cnt=0; last->next=new BuffList; last=last->next; last->NumVK=cnt++; last->next=NULL; }
Alice1144 Код (Text): #include <stdio.h> #include <dos.h> #include <conio.h> #ifdef __cplusplus #define __CPPARGS ... #else #define __CPPARGS #endif const unsigned int MAX_CNT = 256; struct BuffList { unsigned int NumVK; struct BuffList *next; BuffList() { NumVK = 0; next = NULL;} ~BuffList() { NumVK = 0; next = NULL;} } *first, *last; unsigned int cnt = 0; void interrupt get_out(__CPPARGS); void interrupt (*oldfunc)(__CPPARGS); #if defined(__BORLANDC__) static c_break(void) { _disable(); _dos_setvect(0x1c, oldfunc); _enable(); return 0; } #endif void main(void) { clrscr(); first = last = new BuffList; printf("first = %p, first->NumVK = %u\n", first, first->NumVK); oldfunc = _dos_getvect(0x1c); _disable(); _dos_setvect(0x1c, get_out); _enable(); #if defined(__BORLANDC__) ctrlbrk(c_break); #endif delay(100); while (1) { if (first->next == NULL) continue; struct BuffList *next = first->next; delete first; first = next; printf("first = %p, first->NumVK = %u\n", first, first->NumVK); } } void interrupt far get_out(__CPPARGS) { if (cnt == MAX_CNT) cnt = 0; last->next = new BuffList; last = last->next; last->NumVK = ++cnt; } Запускал под wxpprorusp2, dos622 и rescue disk w98se - работает.
1. Зависает сразу на операторе "new" в обработчике прерывания. 2. Иногда прерывание срабатывает, но "new" возвращает NULL, а потом все равно зависает.
Странное решение проблемы. Как-то в универе, когда тоже надо было в проге на Borland C (считай почти то же самое, что и Turbo C) под досом в обработчике прерывания вызывать функции C-шной библиотеки вроде printf и они не работали, я эту проблему решил после пары часов мучений примерно так: Код (Text): unsigned int savedSS; void interrupt handler() { __asm { mov ax,ss mov savedSS,ax push ds pop ss } ... //код обработчика __asm { mov ax, savedSS mov ss,ax } } Короче говоря, оказалось, что SS должен был быть таким же, как и в основной программе, иначе вызовы CRT не работали (причем не просто не работали, а происходил полный ппц). А автоматически сгенерированный компилятором пролог обработчика прерывания, естественно, не меняет SS (что вполне логично), восстанавливает только DS.