Все время компилировал конечную версию программ использую след. алгоритм: 1. Project/Options 2. На вкладке Compiler выбираю Release 3. На вкладке Packages убираю флажок "Build with runtime packages" 4. На вкладке Linker убираю Use Dynamic RTL 5. Компилирую. Проблем с запуском на других компах не было. Написал прогу с одним дочерним потоком, поток создавал функцией _beginthread , собрал на компах с билдером пашет. А на компах без билдера вылетает после захода в поток, на некоторых просто выдает ошибку мол прога лезит не по тому адресу. Как в такой ситуации нужно компилить? ЗЫ: Поток прост и безобиден. В нем ошибки нет.
Извините, конечно, я не Windows программист, но вот у нас, например для потоков нужна libpthread.so Может у вас тоже потоки создаются другой либой, не включенной в поставку билдера? Память не может быть read у вас тогда в коде ошибка. Давайте сорец, буим смотреть
Поток в память не лезет. Он просто фоново вертится в цикле. Эта ошибка вылетает в месте где создаться поток. Походу система обращается по какому-то адресу к функции а там ничего нет.
Создание потока Код (Text): if(T==1){ btnStop->Enabled=True; hTread=_beginthread(CreateOut, 0, NULL ); } Поток Код (Text): //Производит выборку координат //На входе: //На выходе: void CreateOut(void* pParams) { //Определяем минимум и максимум функции //используется при фильтрации float X1=0; //входные данные float X2=0; float h=0; float z0=0; //Инициализация значений X1=StrToFloat(Form1->txtX1->Text); X2=StrToFloat(Form1->txtX2->Text); h=StrToFloat(Form1->txtH->Text); z0=StrToFloat(Form1->txtZ0->Text); //Определяем максимум(минимум) функции по Z float max=0,min=0,Buff=0; max=h+z0; min=z0; if(min>max){ Buff=min; min=max; max=Buff; } //Обрабатываем файл //открываем необходимые файлы AnsiString str1=Form1->txtOpen->Text; //файл с примером AnsiString str2=Form1->txtSave->Text; //сохраняем в std::ifstream MyIn(str1.c_str(),std::ios::in); std::ofstream MyOut(str2.c_str(),std::ios::out); //выход //Пройтись по файлу char str[254]; //буффер для строки char Doc4[]="( 4/"; //начало блока с координатами char EndDoc[]=" )"; int index=0,index1=0,len=0; //счетчик узлов int lenBuf=0; //длина блока float TestX=0,TestZ=0; //текущие координаты MyIn.seekg(0); //перемещаемся в начало файла while(1) //поиск нужного участка { MyIn.getline(&str[0],254); if(strcmp(str,Doc4)==0) //ищем участок с координатами { while(1) { MyIn.getline(&str[0],254); if(strcmp(str,EndDoc)==0) //Проверить на достижение конца break; //Выделить координаты из общей массы и пронумеровать len=strlen(str);//определяем длинну строки int j=0,k=0; //положение в строке char CoordX[16]={0}; char CoordY[16]={0}; char CoordZ[16]={0}; for(int i=0;i<(len-2);i++) { //выделить X for(i;i<len;i++) { if(str[i]!=' ') { if(str[i]!='/') { CoordX[k]=str[i]; k++; } }else break; } CoordX[k]=0; //признак конца строки k=0; i++; //переходим на следующий символ //выделить Y for(i;i<len;i++) { if(str[i]!=' ') { if(str[i]!='/') { CoordY[k]=str[i]; k++; } } else break; } CoordY[k]=0; k=0; i++; //переходим на следующий символ //выделить Z for(i;i<len;i++) { if(str[i]!=' ') { if(str[i]!='/') { CoordZ[k]=str[i]; k++; } } else break; } CoordZ[k]=0; k=0; index++; //индекс узла Form1->Edit3->Text=IntToStr(index); //отображаем текущий индекс //обрезать по X и Z TestX=StrToFloat(CoordX); //текущий Х TestZ=StrToFloat(CoordZ); //текущий Z //Фильтруем узлы в три этапа if(TestX>=X1 && TestX<=X2) //По Х { if(TestZ>=min && TestZ<=max) //По Z { if(TestCoord(TestX,TestZ,X1,X2,h,z0)) //если пренадлежит заданному участку { lenBuf+=IntToStr(index).Length()+1; //длинна записанного блока if(lenBuf>=29000) //максимальная длина не более 30000 байт { MyOut<<"\n\n\n"; //начинаем новый блок lenBuf=0; } index1++; MyOut<<IntToStr(index).c_str()<<" "; //запись в файл Form1->Edit1->Text=IntToStr(index1); //отображаем кол-во отобранных } } } } //end for }//end while break; }//end if }//end while Form1->btnStop->Enabled=False; //+++ } //----------------End CreateOut------------ //Функция определяет пренадлежит ли узел заданному участку //На входе: проверяемые координаты, начальное условие //На выходе: да/нет int TestCoord(float X,float Z,float X1,float X2,float h,float z0) { float min=0,max=0,Buff=0,fZ=0; //получаем тестовое значение fZ=z0+h*sin(3.14*(X-X1)/(X2-X1)); //Функция max=fZ; min=z0; if(min>max){ //определяем большее значение Buff=min; min=max; max=Buff; } //проверяем на принадлежность int i=0; if(Z>=min && Z<=max) i=1; return i; } //----------------End TestCoord------------ Ошибка вызывается даже если поток пуст. Проблема не в коде.
a9d Я в сях не спец, но _beginthread это CRT-шная функция и "This function is available only in the multithread libraries". Может лучше заюзать "родные" VCL-ные BeginThread или TThread ? Им то точно никаких multithread libraries не нужно
CyberManiac Да не-е, по умолчанию cdecl, а автогенерируемым заготовкам VCL-ных кликов автоматам приписывается _fastcall Если только сам ручками в настройках изменил на register, и то врядли, т.к. и передаваемый параметр не использ-ся, а при cdecl вызывающая прога сама стек чистит, ну и на компе с билдером вроде "пашет" PS: Вообще, BCB это какой-то странный гибрид В частности все (достаточно толковое) описание работы с тредами взято из дельфей и в основном касается TThread и мельком BeginThread, а описание сишной _beginthread существует само по себе, и не понятно что эта функция делает и можно ли ее юзать с VCL и Ansistring (для этого нужно как минимум установить переменную System::IsMultiThread = true).
a9d Наконец глянул код потока и ужаснулся Прописная истина - визуальные VCL-компоненты не являются потокобезопасными, даже читать св-ва контролов из другого потока не рекомендуется, не говоря уже о записи - иначе возможны глюки. Лучше всего убрать из потока обращения к форме или на крайняк юзать для этого TThread.Syncronize (но это доп.тормоза, т.к. происходит переключение на основной поток)
Исключил обращение к форме. Добавил библиотеки borlndmm.dll , cc3260.dll , cc3260mt.dll. Эффекта ноль. Да и вообще вылетает даже пустой поток. ЗЫ: с _beginthreadNT тоже не пашет.
a9d Создавал и пустой и не пустой поток. Из потока и читает с компонент и пишет,все ок выложи целиком проект плз
a9d Мда, тебе что нужно "шашечки или ехать", непременно "победить" некий _beginthread или чтобы прога работала ? Объясняю еще раз. Все вариации beginthread-ов являются обертками над виндовой CreateThread и выполняют доп.действия для обеспечения потокобезобасности используемых библиотек. Если пишешь на "чистом" С\С++ с CRT, то юзаешь CRT-шную _beginthread(ex). Если юзаешь MFC, то нужен AfxBeginThread или класс CThread. Если юзаешь VCL и AnsiString, то будь добр юзать System::BeginThread или класс TThread. C VCL можно и виндовую CreateThread юзать, если предварительно установить IsMultiThread = true, а в функции потока первым делом вызвать Set8087CW(Default8087CW) для инициализации FPU (если он юзается явно или неявно) и заключить тело функции в try\except (иначе в сл.ошибки вся прога слетит)