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


Автор: TGrey 6.5.2010, 17:07
Здравствуйте, задали на лабаре сделать любую программу, которая использует функции написанные на других языках. Используя только метод подключения объектных файлов. Я слышал про такое, но никогда не интересовался, как это делается. Зашли в гугл на паре, полистали странички, нашли пару примеров, один из которых делает именно то что надо. Из Борланда С++, вызывает функцию на Делфи написанную.
Но что мы не писали и как не старались оно так и не заработало.
Сперва ели додумались как в Делфи генерировать объектный файл, а поскольку там в опциях 2 радио кнопки, С и С++ файлы перепробовали с обоими. Тоже ничего. А С++ компилятор после добавления того объектного файла постоянно выдавал ошибку 
Цитата

Fail. Access violation. Terminating

В общем умного ничего не придумали, подскажите, как это нужно делать или может, где-то есть статья или еще что.
Спасибо.

Автор: PhoSor 11.5.2010, 10:59
Под каким компилятором исполняемый файл собирать самому догадаться надо?

Автор: GoldFinch 11.5.2010, 11:58
TGrey, 
убедитесь что создаваемый .obj имеет формат COFF (настройки компилятора),
попробуйте линковать через командную строку (link.exe)

Добавлено через 1 минуту и 41 секунду
PhoSor, собирает линкер, а не компилятор. Линкер универсальный для всех компиляторов, если у obj, которые создает компилятор, стандартый формат.

Автор: TGrey 11.5.2010, 16:03
Да я уже получил консультацию по этому вопросу) Дело в том, что тот пример, что описан вышел собирался в Борландовских Делфях и в Борл. С++. И именно там была та ошибка.
Когда я попробовал из Делфи в Студию перенести, то я получил сообщение, что не может преобразовать формат, как раз COFF.
В общем дело все свелось к тому, что у меня кроме МАСМа нет больше никаких Майкрософтовых компиляторов, а если уже и на то пошло, то другие языки программирования тоже не ахти знаю, как там это все реализовано.
Попросил людей на МАСМе накатать пару легких функций, но все ушли в подполье( А всего-то нужно пару строк, потому, что работа полностью не состоит из этой темы, а просто затрагивает ее. Вот и нужно любая функция на другом языке, чтобы ее подключить к Студии.
Может можете тут помочь? Язык любой, компилятор Майкрософта.
Спасибо.

Автор: Abyx 11.5.2010, 17:38
TGrey, ну вот вам COFF на фасме
Код


; example of making Win32 COFF object file

format MS COFF

extrn '__imp__MessageBoxA@16' as MessageBox:dword

section '.text' code readable executable

 public _demo

 _demo:
    push    0
    push    _caption
    push    _message
    push    0
    call    [MessageBox]
    ret

section '.data' data readable writeable

 _caption db 'Win32 assembly',0
 _message db 'Coffee time!',0

(см. аттач)

Автор: TGrey 11.5.2010, 19:40
Эммм, а как вызывать то функцию? Я так понимаю, что она выводил МеседжБокс, но параметры?
Код

//extern "C" int _stdcall Mes(HWND, LPCSTR, LPCSTR, UINT);

Попробовал ничего не вызывает.
Цитата

Linking...
1.obj : error LNK2001: unresolved external symbol _Mes@16
Debug/diit6.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

Автор: Abyx 11.5.2010, 19:43
TGrey, там экспортируется "_demo"

extern "C" void _demo(void); 
или
extern "C" void __stdcall demo(void);

Автор: TGrey 11.5.2010, 20:14
Что-то все равно не очень
Код

Linking...
1.obj : error LNK2001: unresolved external symbol _demo@0
Debug/diit6.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

Автор: Abyx 11.5.2010, 20:24
значит я неугадал, и там не __stdcall
вообще логично, раз @xx нет, значит не __stdcall
значит __cdecl
extern "C" void __cdecl _demo(void); 
или
extern "C" void __cdecl demo(void); 

(не помню как манглинг __cdecl выглядит)

Автор: TGrey 11.5.2010, 21:15
О есть
Код

extern "C" void _cdecl demo(void); 

int main()
{
    demo();
    return 0;
}


А случайно нет ли еще может одной функции какой-то? smile 


Еще хотел спросить ФАСМ, это майкросовтовский? Или как его объектный файл подходит?

Автор: Abyx 11.5.2010, 21:51
TGrey, фасм не майкрософтовский, просто он умеет генерить MS COFF
flatassembler.net

т.к. demo - __cdecl, то ей можно задать любую __cdecl сигнатуру, и она всеравно будет работать

например
Код

extern "C" Foo* __cdecl demo(int&, float, char*);


надо менять ей имя -  скачайте фасм и меняйте ей имя пока не надоест.

вот вам минимальный шаблон с 3я функциями
Код

format MS COFF

section '.text' code readable executable

 public _func1
 public _func2
 public _func3

 _func1:
 _func2:
 _func3:
        ret

Автор: Abyx 11.5.2010, 21:55
для __stdcall надо их назвать 
func@xx
где xx - 4*число агрументов
и вместо ret написать ret xx
Код

public stdcall_3arg_func@12 ; 12 = 3*4
stdcall_3arg_func@12:
ret 12

Автор: TGrey 11.5.2010, 22:17
Дело в том, что я не знаю АСМ) Собираюсь начать изучать, но руки никак не доходят.
Я понимаю, что шаблон есть, но я то не знаю через какие регистры передавать параметры и как это правильно делать)

Кстати, я вроде читал что там вроде 4*кол-во должно быть. sizeof(type)*кол-во?

В общем я так и сижу вникаю с чего начинать, ТАСМ, ФАСМ, МАСМ, везде синтаксис разный 0_о тут хоть бы основы выучить, а что дальше выбрать smile 

Автор: Abyx 11.5.2010, 23:16
TGrey, если вам не надо писать код функции - то вам не надо знать асм

4*количество_аргументов
0 аргументов, func(void) - func@0
1 аргумент, func(T1 arg1) - func@4
2 аргумента, func(T1 arg1, T2 arg2) - func@8
....

под "аргументом" понимается тип размером не больше dword.
типы большей длины считаются за несколько аргментов, например double - 8 байт, как 2 аргумента,
но это редкие случаи.

Автор: PhoSor 12.5.2010, 10:41
Виноват, забыл что gcc юзаю. Там и компилятор и линкер в через один исполняемый работают.
И еще я птму и спрашивал про компилятор, чтобы узнать какой формат на выходе у объектного файла будет. Птму как некоторые кроссплатформенные компиляторы без пинка могут код записать в файлик с ELF оберткой.
Ну и про линкеры, я думаю, имелась ввиду универсальность не компиляторов, а форматов объектных файлов.

Автор: TGrey 12.5.2010, 15:42
Как это чтобы писать код функции не нужно знать асм? А что ж я буду в тело функции писать?)
К примеру я захочу написать функцию которая возвращает большее из 2 параметров.
Сравнивать я буду видимо через cmp а дальше то что? Я думаю, что мне нужно знать асм)

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