в файле obj к функциям добавляются какие-то цифры и нижняя черточка перед _функция@8 _функция@0 _функция@4 и линкер не может понять их unresolved external symbol _SendReply@8 unresolved external symbol _MainSockListen@0 unresolved external symbol _ServeThread@4 что это???
это количество аргументов функции измеренной в байтах наверное пытаешься прикрутить чужой линкер у масма в штатном варианте всё прекрасно понимает )
Это манглинг имён называется, цифра означает суммарный размер параметров в байтах. _Function@SIZE - это stdcall @Function@SIZE - это fastcall _Function - это cdecl и так далее
а почему возникают такие ошибки, если у меня в программе есть функции SendReply, MainSockListen, ServeThread без всяких цыфр?
Satell "у меня в программе" - это где? Покажите как обьявлен прототип одной из этих функций в модуле, который её содержит, и в модуле, который её вызывает. Вероятно, в первом случае используется соглашение cdecl, а во втором - stdcall.
Satell Это происходит из-за расхождений в описании функции при ее определении и объявлении. Как здесь уже упоминали во всем "виновата" конвенция вызова, которая родилась с появлением языков высокого уровня и по сути своей не применима к низкоуровневым языкам, типа ассемблера, где компилятор-транслятор сам _не_ строит исполнимый код, а лишь переводит соответствующие мнемоники в байт-код. Одной из главных задач трансляторов с ЯВУ является правильная генерация кода программы для случаев передачи управления внешним процедурам, например, посредством инструкции call и контроль за состоянием программного стека в эти моменты. Так как функции теперь умеют быть "перегруженными"(имя одно, а принимаемых параметров переменное кол-во), а также могут сами очищать со стека параметры, переданные им из вызывающей процедуры(эта фича также и для уменьшения размеров программ), нужно было придумать эффективный способ для правильной реализации этих механизмов во время связывания "объектников". Красивым решением оказалось - кодировать всю необходимую инф-ию через само имя вызываемой процедуры. Т.е. транслятор видя, например, объявление такой функции: Код (Text): // #define WINAPI __stdcall extern int WINAPI foo( char *a ); знает, что если далее в листинге ему встретится её вызов, ему нужно будет сгенерировать: 1. Код по передаче одного параметра через стек 2. Код по передаче управления на эту функцию А вот строить код для очистки параметра со стека после вызова уже не потребуется, т.к. стек уже будет выровнен вызываемой процедурой(__stdcall). Плюс к этому, в сгенерированный объектный файл он запишет правильно замангленное имя-метку, которое будет использоваться позже линкером в процессе связывания - _foo@4. И, соотв-но, линкер при окончательном построении программы в момент вычисления адреса метки будет искать такое и _только_ такое _foo@4 во всех указанных ему объектниках/либах. Т.е., как уже сказал Quantum, проблема скорее всего в __cdecl VS __stdcall