Open Watcom

High-level languages programming questions
  • Я проверил адреса полей структур. Я реализовал вывод адресов полей структуры внутри функции LoadSpectra()
    и после вызова функции. Почему-то после вызова функции адреса полей структуры info смещаются на 4 байта,
    а структуры plot на 7 байт. Из-за этого читаются неправильные данные. Только вот почему происходит смещение адресов - непонятно.
    KolibriOS-перспективная ос!
    Kolibri is best operation system in the world!
  • andrew_programmer
    Почему-то после вызова функции адреса полей структуры info смещаются на 4 байта,а структуры plot на 7 байт
    А до вызова ? Скорее всего это разные опции выравнивания при компиляции. Выравнивание по умолчанию 8 байт. После int смещение будет 4 после char 7 байт. Это легко проверить если посмотреть дизассемблированный листинг. В Ide открываешь на файле контекстное меню правой кнопкой мыши Disassemble -> Edit disassemble.
    Если скинешь мне все исходники я смогу проверить другие варианты.
  • Вывод адресов структуры показал, что до вызова функции и после вызова адреса полей совпадают. А вот в самой функции адреса смещаются. В IDE я выбрал опцию 1 byte aligment вместо Default byte aligment и проблема с адресами структур исчезла. Потом я упаковал все структуры через #pragma pack(1) и вернул Default byte aligment. Теперь проблемы со смещением нет. Но появилась другая проблема :) После создания интерфейса вызывается функция Plot() , которая строит спектры(экспериментальные, теоретические и т.д.). Экспериментальный спектр строится нормально, а потом где-то в функции Plot() из-за чего-то происходит вылет. Понятия не имею - где и почему.
    Если скинешь мне все исходники я смогу проверить другие варианты.
    Исходники конечно могу скинуть. Главное знать куда скидывать - электронного ящика в профиле нет. :)
    P.S
    Мда... Сам язык программирования C платформенно независим, а вот программа, написанная на нём и разработанная определённым компилятором, зависит от этого компилятора. Получается, что, то что компилируется и работает с одним компилятором, может не работать с другим :( Вот такие "пироги" ....
    KolibriOS-перспективная ос!
    Kolibri is best operation system in the world!
  • Я выяснил, почему происходит вылет программы в функции Plot().
    В файле kolibrisys.h реализованы несколько макросов: va_list,va_start,va_end.
    OpenWatcom не ругается на эти макросы - он просто генерирует неправильный код.
    В результате функции vsnprintf() передаётся неправильный лист параметров и происходит
    вылет программы. Хотя эти же самые макросы компилируются GCC и работают правильно.
    Я закомментировал эти макросы и использовал макросы из stdarg.h(поставляется
    вместе с Watcom-ом).Функция Plot() вылетать перестала. Сейчас продолжаю разбираться
    с другими приколами компилятора OpenWatcom.
    KolibriOS-перспективная ос!
    Kolibri is best operation system in the world!
  • andrew_programmer
    Это потому что Ватком передаёт часть параметров в регистрах. Вообще если пользуешься стандартными макросами и заголовочными файлами надо всегда брать родные.

    Мой ящик ion2<собака>mail.ru
  • Serge

    Отправил.
    KolibriOS-перспективная ос!
    Kolibri is best operation system in the world!
  • andrew_programmer

    У меня нет kolibrisys.lib
  • Я как раз об этом толькочто вспомнил.
    Когда собирал архив, старался ничего не забыть. И как на зло забыл положить библиотеку kolibrisystem.lib

    Отправил.
    KolibriOS-перспективная ос!
    Kolibri is best operation system in the world!
  • andrew_programmer

    Code: Select all

    //find simbol '/'
                    i=1023;
                    while(filename[i]!='/')
                    {i--;}   
                    //copy name
                    for(j=0;j<=i;j++)
                    {
                            outfilename[j]=filename[j];
                    }
                    for(j=0;j<14;j++)
                    {
                            outfilename[i+j+1]=name[j];
                    }
    Этот код не работает. Длина командной строки 256 байт вместе с завершающим нулём Я заменил эту часть на

    Code: Select all

              char *p;
              int pathsize;
                    //check for file colibrovka.txt
                    outfilename=malloc(256);
    
              p = strrchr(filename,'/');
              if(p != 0)
              {
                pathsize = p-filename+1;
                memcpy(outfilename, filename, pathsize);
                memcpy(outfilename+pathsize, name, 15);
              }
              else
                memcpy(outfilename, name, 15);
    
    С этими исправлениями программа загружается.

    Во-вторых SendMessage просто убийца для программ на С. Не сохраняет ни одного регистра, меняет esi и edi.
  • Serge

    Большое спасибо!
    Наконец-то программа заработала.
    Этот код не работает. Длина командной строки 256 байт вместе с завершающим нулём
    Мне почему-то казалось, что 1024. Видно GCC как-то перестраховывался от этой ошибки. Я подправил код и в других местах - теперь всё работает.
    Во-вторых SendMessage просто убийца для программ на С. Не сохраняет ни одного регистра, меняет esi и edi.
    Я недавно добавлял в libGUI сохранение регистров после входа в функции. Во все функции добавил, а про SendMessage() забыл.
    Добавлю.

    Ещё раз большое спасибо.
    KolibriOS-перспективная ос!
    Kolibri is best operation system in the world!
  • Обнаружилась ещё одна проблема, которая, как мне кажется, связана с libC.

    Если в любой части функции LoadSpectr() вставить код открытия и закрытия какого-либо файла, то с указателями происходит что-то непонятное. После заполнения структур для libGUI данные в них оказываются какие-то другие. Хотя если код открытия и закрытия какого-либо файла убрать, то структуры заполняются правильно.

    Вот я в код добавляю открытие закрытие файла:

    Code: Select all

            //load spectr from file to memory
            buffer=malloc(60*1024);
    
            f=fopen(filename,"rb");
    
    	if (f!=NULL)
    	{
            	i=0;
            	while((j=fgetc(f))!=EOF)
            	{
                    	buffer[i]=j;
                    	i++;
            	}
    		fclose(f);
    	}
    	else
    	{	
    		free(buffer);
    		return(-1);
    	}
    
            buf_size=i-1;
    	/*
    	f=fopen("autorun.dat","rb");
    	fclose(f);
            */


    Если код раскомментировать, то программа работать небудет, а если оставить закомментированным, то программа работает.
    KolibriOS-перспективная ос!
    Kolibri is best operation system in the world!
  • Serge

    Проводил эксперименты с кодом и обнаружил странные вещи.
    Я менял положение финкции LoadSpectra() в коде программы. С точки зрения логики работы программы это не имеет никакого значения. А вот с точки зрения генерации кода, свободного от ошибок, как оказалось, имеет.

    Вот часть кода :

    Code: Select all

    int main(int argc, char **argv)
    {
      char                                          exit_status;
      struct        WINDOW                          *win;
      struct        SCREEN                          *scr;
      struct        PLOTINFO                        *plot;
      struct        lorents_information             *lorents;
      struct        X                               *x_c;
      struct        HEADER                          *Parend;
      struct        MESSAGE                         *Message;
      struct        process_table_entry             *ProcessInformation;
      struct        ControlBookmark2                *Bookmark2;
      struct        ControlProgressbar              *CalculationProgress;
    
      dword                                         *controls;
      dword						x,y,mouse_buttons;
      int                                           i;
      int                                           key;
      int                                           count_iteration;
      float                                         step_iteration;
      unsigned      char                            sound_end_calculation[]={150,64,0,0,0};
      char                                          *pathspectr;
      char						*ptr;
      char						c;
      FILE*                                         f;
    
    
      pathspectr=argv[1];
    
      win=malloc(sizeof(struct WINDOW));
      lorents=malloc(sizeof(struct lorents_information));
      x_c=malloc(sizeof(struct X));
      scr=malloc(sizeof(struct SCREEN));
      plot=malloc(sizeof(struct PLOTINFO));
    
    //  variant 1
    //  LoadSpectra(pathspectr,lorents,plot,scr);
    
      _ksys_set_wanted_events(0x67);
      
      count_iteration=0;
    
      Init_libGUI();
    
      win->posx=WINDOW_POSX;
      win->posy=WINDOW_POSY;
      win->sizex=WINDOW_SIZEX;
      win->sizey=WINDOW_SIZEY;
      
      draw_window(win);
    
    //  variant 2 
    //  LoadSpectra(pathspectr,lorents,plot,scr);
      
      controls=malloc(TOTAL_NUMBERS_OF_CONTROLS*100);
      Parend=(struct HEADER *)malloc(sizeof(struct HEADER));
      Message=(struct MESSAGE *)malloc(sizeof(struct MESSAGE));
      ProcessInformation=malloc(sizeof(struct process_table_entry));
    
    //  variant 3 (work variant)
      LoadSpectra(pathspectr,lorents,plot,scr);
    
      CraeteInterface(controls,Parend,win,scr,plot);
      DisplayInformation(controls,lorents);
     
      Message->type=MESSAGE_FULL_REDRAW_ALL;
      Message->arg1=0;
      Message->arg2=0;
      Message->arg3=0;
    
      SendMessage(Parend,Message);
      
    


    Если раскомментировать первый вариант, то программа вылетает из-за неправильного содержимого структур для libGUI(почему-то меняется содержимое заполняемых структур).

    Если раскоментировать второй вариант,то структуры для libGUI заполняются правильно, если в директории,где находится программа, нет файла colibrovka.txt (тоесть, если не загружается этот файл).

    В случае третьего варианта расположения функции, программа работает так, как ей и положено работать согласно коду программы.

    Почему происходят такие странные вещи - я покачто не выяснил.
    KolibriOS-перспективная ос!
    Kolibri is best operation system in the world!
  • В новой версии libC для OpenWatcom-а, что на нашем SVN, в проекте установлена модель памяти small. А чем она отличается от flat ? Её можно применять для выделения больших объёмов памяти в сотни мегабайт ?

    Я просматривал дизассемблированный листинг кода, сгенерированного watcom-ом, там в вычислениях с плавающей запятой часто встречается строка call __CHP . Что это такое ?
    KolibriOS-перспективная ос!
    Kolibri is best operation system in the world!
  • andrew_programmer

    Для NT small=flat. Означает отсутствие дальних указателей sel:offset. __CHP оболочка для frndint.

    Я думаю что твой разрушает кучу malloс. Одиночные структуры лучше располагать в стеке.
  • Who is online

    Users browsing this forum: No registered users and 5 guests