Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Компиляция самодостаточной функции в obj(lib) файл


Автор: Slash_from_Rjazan 11.5.2007, 11:02
Вобщем задача такая.
Есть функции:
Код

int _pascal save_to_file(int fileNo, float *a, float *b){
 char FileName[255];
 FILE *stream;
 sprintf(FileName,"%s%i",BASENAME,fileNo);
 stream=fopen(FileName,"wt+");
 fprintf (stream,"%f %f",*a,*b);
 fclose(stream);
 return 1;
};

int _pascal read_from_file(int fileNo,float *a, float *b){
 char FileName[255];
 FILE *stream;
 sprintf(FileName,"%s%i",BASENAME,fileNo);
 stream=fopen(FileName,"rt+");
 fscanf (stream,"%f %f",a,b);
 fclose(stream);
 return 1;
};

Необходимо из них получить obj(lib) файл так, что прилинковав его к произвольному проекту этими функциями можно было лекго пользоваться без использовния дополнительных библиотек...
Сейчас программа, использующая эти функции из obj файла ,полученного обычным способом, вываливается с сообщением:
"floating point formats not linked
Abnormal program termination"

Автор: nerezus 11.5.2007, 11:43
Цитата

_pascal
 Что эт за хрень? убираем, компилер ругается.

И дай пример вызова.
P.S. У меня просто вываливается "программа выполнила недопустимую операцию, но я вроде не так ее вызывал"

Автор: EnergoHokum 11.5.2007, 12:05
Не _pascal, а __pascal, это аналог __stdcall, если не путаю.

Добавлено через 9 минут и 16 секунд
И если уж работаешь на плюсах, может лучше использовать <iostream>? Зайди на http://www.cplusplus.com/reference/iostream/ , там много интересного.

Автор: Slash_from_Rjazan 11.5.2007, 12:18
У меня Borland C++ 3.1.
Директива _pascal определяет порядок формирования имени функции и передачи в нее параметров -- при простой компиляции ее наличие или отсутсвие никак не сказывается.

Пример вызова дать не могу ибо вызываю это дело при создании проекта в среде UltraLogik, предназначенной для создания ПО для контроллеров. На контроллере на платфоме x86 работает под DOS.

Приаттачу exe файл проекта -- его можно запустить хоть в консоле ХР -- ошибку как у меня увидите...
(Знаю, что посылать exe нехорошо, но другого варианта в данном случае нет...)

Автор: EnergoHokum 11.5.2007, 12:50
Такое ощущение, что у тебя не прилинкована библиотека работы с float, ругань на "floating point formats not linked" и "Null pointer assignment Divide error" вкомпилирована прямо в файл.

Автор: Slash_from_Rjazan 11.5.2007, 13:21
Хм, сообщение об ошибке я и сам перевел...
Вопрос именно в том как это все туда влинковать!!!

Автор: EnergoHokum 11.5.2007, 13:55
То есть, ты пытаешься компилировать *.cpp именно в таком виде, как привёл в первом посте? Без #include <нужный_заголовочный_файл.h>?

Автор: Slash_from_Rjazan 11.5.2007, 14:31
Я пытаюсь компилировать следующий исходник:
Код

#include <STDLIB.H>
#include <STDIO.H>
#define BASENAME "D:\\"
int _pascal save_to_file(int fileNo, float *a, float *b){
 char FileName[255];
 FILE *stream;
 sprintf(FileName,"%s%i",BASENAME,fileNo);
 stream=fopen(FileName,"wt+");
 fprintf (stream,"%f %f",*a,*b);
 fclose(stream);
 return 1;
};

int _pascal read_from_file(int fileNo,float *a, float *b){
 char FileName[255];
 FILE *stream;
 sprintf(FileName,"%s%i",BASENAME,fileNo);
 stream=fopen(FileName,"rt+");
 fscanf (stream,"%f %f",a,b);
 fclose(stream);
 return 1;
};

Автор: EnergoHokum 11.5.2007, 15:56
Фффух!!! Утомил ты меня, однако! Под конец раб. недели моск плохо работает. Собрал я это под GCC, если что, я до понедельника в инете не буду, но получилось так:
_pascal я заменил на __stdcall, бо GCC _pascal не ест, и в файле, из которого делать exe-шник перед main() добавил упреждающее объявление функций:
Код

#include <iostream>

int __stdcall save_to_file(int fileNo,float* a,float* b);
int __stdcall read_from_file(int fileNo,float* a,float* b);

int main(int argc,char** argv)
{
    std::cout<<"Run"<<std::endl;
    float f1=3.14159,f2=9.0000012345;
    save_to_file(1000,&f1,&f2);
    return 0;
}

Всё заработало, файл создался, что нужно - записалось туда. Ну всё, до понедельника. ИК!!!

Добавлено через 1 минуту и 23 секунды
На всякий случай, держи Makefile:
Код

REMOVE = rm -f
INEXECUTE = main
OUTEXECUTE = prog
INLIB = file
OUTLIB = libTest

$(OUTEXECUTE) : $(INEXECUTE).o
    g++ -o $(OUTEXECUTE) $(INEXECUTE).o -L "e:/Hokum/Program/CPP/testVingrad" -lTest
$(INEXECUTE).o : $(INEXECUTE).cpp
    g++ -c $(INEXECUTE).cpp
$(OUTLIB) : $(INLIB).o
    ar crf $(OUTLIB).a $(INLIB).o
    ranlib $(OUTLIB).a
$(INLIB).o : $(INLIB).cpp
    g++ -c $(INLIB).cpp

exe :
    $(MAKE) $(OUTEXECUTE)
lib :
    $(MAKE) $(OUTLIB)
clean :
    $(REMOVE) $(OUTLIB).lib
    $(REMOVE) $(INLIB).o
ALL : clean lib exe

Автор: Любитель 11.5.2007, 19:03
Цитата(Slash_from_Rjazan @  11.5.2007,  12:18 Найти цитируемый пост)
У меня Borland C++ 3.1.

Цитата(Slash_from_Rjazan @  11.5.2007,  13:21 Найти цитируемый пост)
Вопрос именно в том как это все туда влинковать!!!

Какие-то ключи компилера должны быть. Смотри его доки. Или приведи нам - разберёмся.

ЗЫ У меня такого компилера нет и вживую его никогда не видел smile

Автор: JackYF 11.5.2007, 20:57
Цитата(Любитель @  11.5.2007,  19:03 Найти цитируемый пост)
ЗЫ У меня такого компилера нет и вживую его никогда не видел smile 


У-у, ты много потерял smile Могу выложить это антикварное чудо или в личку переслать. Поржать. У нас этого добра в универе навалом.

Автор: Slash_from_Rjazan 11.5.2007, 23:15
Компилятор может и староват...
Говорите ключи искать, а хоть в каком направлении? Как требуемая мне возможность называться может?

Кстати, может быть вы сразу посоветуете мне какой-либо другой способ решит мою задачу? Т.е. использовать другой язык, может быть системные вызовы ДОС? Важно только, чтобы можно было получить obj файл с функциями...

Автор: Любитель 11.5.2007, 23:47
Slash_from_Rjazan, как ты вообще всё собираешь?

1. Файл с функциями как компилешь?
2. Файл, юзающей их - тот же вопрос.
3. Как всё сие линкеришь?

Автор: Slash_from_Rjazan 12.5.2007, 16:14
1. Файл с функциями как компилешь?
Выставляю нужные мне параметры модели памяти (Medium), далее меню Compile->Make. В папке с проектом получаю obj-файл
2. Файл, юзающей их - тот же вопрос.
Этот файл компилируется средой UltraLogik, на выходе тоже получается obj файл
3. Как всё сие линкеришь?
С помощью tlnik:
tlink c0m.obj+Save.obj+kontr.obj,kontr,,cm.lib

У меня уже есть подозрение, что нужно подключить при линковке еще какую-либо библиотеку или модуль, надо только узнать какую...

Автор: Любитель 12.5.2007, 19:37
Slash_from_Rjazan, во-первых, точно сказать ничего не могу. Во-вторых, если я правильно понял - один файл компилтся с одной среды, другой - с другой? Очень вероятно, что они по-разному играются с ключами компилера. Лучше всё компилить из одного источника.

И ещё - приведи вызывающей код. На всякий случай. Не пойму, причём тут вещественная арифметика...

Автор: Damarus 13.5.2007, 13:20
http://www.faqs.org/faqs/msdos-programmer-faq/part2/section-5.html

Автор: Slash_from_Rjazan 1.6.2007, 09:58
Проблема решилась правильным заданием порядки библиотек в опциях линкера.
Вот выдержка из мануала:
        UNDEFINED SYMBOL WHEN TLINKING FROM DOS COMMAND LINE
             The TLINK command line must have the libraries in the
             following order ( GRAPHICS.LIB +  + EMU.LIB
             + MATH (S,T,C,M,L - for model) + C (S,T,C,M,L - for
             model)

Т.е. получилось так: tlink  /v /Tde C0m.obj+Main.obj+Save.obj,Main,,Emu.LIB+Mathm.lib+cm.lib

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)