Уже несколько дней пытаюсь заставить работать скомпилированную OpenWatcom-ом мою
научную программу. Для работы программы используются функции из libC и минимум
прямых обращений к системным функциям(функции из файла kolibrisys.h)
Необходимые обёртки системных функций я переделал под OpenWatcom. Это объектные
файлы формата MS COFF.Регистры в ассемблерных функциях сохраняются в стеке, чтобы
не возникало конфликтов с кодом, генерируемым Watcom-ом.Структуры упакованы через
#pragma pack(1). Я компилировал Watcom-ом тестовую программу, использующую libGUI,
она работает.
В коде моей программы нет ничего специфичного для компилятора.C код программы
платформенно независим.
Сама программа компилируется.Я открываю ей файл со спектром и программа вылетает.
Я выискивал место вылета программы. И пришёл к выводу - дело не в моей программе,а
в компиляторе OpenWatcom или в libC...
Вот в чём дело.
Загрузка спектра и вычсисление начальных параметров из спектра происходит в функции
LoadSpectra. Если раскоментировать часть кода, выводящую проверочную информацию в
файл и скомпилировать, то проверочная информация показывает, что спектр загружается
правильно и начальные параметры из него опрееляются правильно. Вот код функции:
Code:
void LoadSpectra(char *file,struct lorents_information *info,struct PLOTINFO *plot,struct SCREEN *scr)
{
int i;
FILE* f;
info->spectr=malloc(SPECTRA_BUFFER_SIZE);
info->spectr_theoretical=malloc(SPECTRA_BUFFER_SIZE);
info->spectr_restored=malloc(SPECTRA_BUFFER_SIZE);
info->P_H=malloc(SPECTRA_BUFFER_SIZE);
LoadSpectr(file,info);
GetParametersLoadedSpectr(info);
//f=fopen("spectra.txt","wb");
//for(i=0;i<1000;i++) {fprintf(f,"\n\r%d = |%6.1f|",i,info->spectr[i]);}
plot->type_plot=PLOT_SPECTRA_N_EXPERIMENTAL;
plot->Nmin=info->Nmin;
plot->Naverege=info->Nbusis;
plot->Nmax=info->Nmax;
plot->Nspectr=info->spectr;
plot->Nspectr_theoretical=info->spectr_theoretical;
plot->ChannelMax=info->length_spectr-1;
plot->ChannelMin=0;
plot->ChannelNull=info->ChannelNull;
plot->VelosityMax=info->vmax;
plot->VelosityMin=info->vmin;
plot->Pmax=1.0;
plot->Pmin=info->Nmin/info->Nmax;
scr->PlotP_H=MODE_SHOW_SPECTR;
/*
fprintf(f,"\n info->Nmin=%6.6f",info->Nmin);
fprintf(f,"\n info->Nbusis=%6.6f",info->Nbusis);
fprintf(f,"\n info->Nmax=%6.6f",info->Nmax);
fprintf(f,"\n plot->ChannelMax=%6.6f",plot->ChannelMax);
fprintf(f,"\n plot->ChannelNull=%6.6f",plot->ChannelNull);
fprintf(f,"\n plot->VelosityMax=info->vmax;=%6.6f",info->vmax);
fprintf(f,"\n plot->VelosityMin=info->vmin=%6.6f",info->vmin);
fprintf(f,"\n plot->Nmin=%6.6f",plot->Nmin);
fprintf(f,"\n plot->Naverege=%6.6f", plot->Naverege);
fprintf(f,"\n plot->Nmax=%6.6f",plot->Nmax);
fprintf(f,"\n plot->ChannelMax=%6.6f",plot->ChannelMax);
fprintf(f,"\n plot->ChannelNull=%6.6f",plot->ChannelNull);
fprintf(f,"\n plot->VelosityMax=info->vmax;=%6.6f",plot->VelosityMax);
fprintf(f,"\n plot->VelosityMin=info->vmin=%6.6f",plot->VelosityMin);
fclose(f);
*/
}
Но! Если сразу же после вызова функции LoadSpectra вывести этиже параметры(из тех же
структур) в другой файл, то они окажутся совершенно другими. Это значит, что чтение
данных происходит из другой области памяти. При компиляции GCC такой проблемы не
возникает. Как вы видели программа нормально работает.
Вот код, где происходит вызов функции LoadSpectra и запись параметров в другой файл:
Code:
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;
FILE* f;
pathspectr=argv[1];
printf("\n\rpath=%s",pathspectr);
_ksys_set_wanted_events(0x67);
count_iteration=0;
printf("\n\rbegin init libGUI");
Init_libGUI();
printf("\n\rlibGUI initialized succesfull.");
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));
win->posx=WINDOW_POSX;
win->posy=WINDOW_POSY;
win->sizex=WINDOW_SIZEX;
win->sizey=WINDOW_SIZEY;
printf("\n\rbegin load spectra");
LoadSpectra(pathspectr,lorents,plot,scr); //------------------------------------------------
f=fopen("info.txt","wb");
fprintf(f,"\n info->Nmin=%6.6f",lorents->Nmin);
fprintf(f,"\n info->Nbusis=%6.6f",lorents->Nbusis);
fprintf(f,"\n info->Nmax=%6.6f",lorents->Nmax);
fprintf(f,"\n plot->ChannelMax=%6.6f",plot->ChannelMax);
fprintf(f,"\n plot->ChannelNull=%6.6f",plot->ChannelNull);
fprintf(f,"\n plot->VelosityMax=info->vmax;=%6.6f",plot->VelosityMax);
fprintf(f,"\n plot->VelosityMin=info->vmin=%6.6f",plot->VelosityMin);
fclose(f);
printf("\n\rspectra loaded");
draw_window(win);
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));
printf("\n\rbegin create interface");
CraeteInterface(controls,Parend,win,scr,plot);
printf("\n\rinterface created");
printf("\n\rbegin display information");
DisplayInformation(controls,lorents);
printf("\n\rinformation displayed");
Message->type=MESSAGE_FULL_REDRAW_ALL;
Message->arg1=0;
Message->arg2=0;
Message->arg3=0;
printf("\n\rbegin send first message");
SendMessage(Parend,Message);
printf("\n\rmessage sended");
Как видно вызов функции LoadSpectra происходит ещё до создания интерфейса, поэтому
функции libGUI тут непричём.