при компиляция к функциям добавляются цифры

Тема в разделе "WASM.BEGINNERS", создана пользователем Satell, 19 июн 2007.

  1. Satell

    Satell New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    23
    в файле obj к функциям добавляются какие-то цифры и нижняя черточка перед _функция@8 _функция@0 _функция@4 и линкер не может понять их
    unresolved external symbol _SendReply@8
    unresolved external symbol _MainSockListen@0
    unresolved external symbol _ServeThread@4
    что это???
     
  2. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Это stdcall конвенция вызова. Подробнее тут.
     
  3. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    это количество аргументов функции измеренной в байтах ;)
    наверное пытаешься прикрутить чужой линкер ;) у масма в штатном варианте всё прекрасно понимает :))
     
  4. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Y_Mur
    Да, но только если указать либу или обьектник, в котором эти символы живут - он же не телепат!
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Это манглинг имён называется, цифра означает суммарный размер параметров в байтах.

    _Function@SIZE - это stdcall
    @Function@SIZE - это fastcall
    _Function - это cdecl
    и так далее
     
  6. Satell

    Satell New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    23
    а почему возникают такие ошибки, если у меня в программе есть функции SendReply, MainSockListen, ServeThread без всяких цыфр?
     
  7. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Satell

    Как правильно написал Quantum
    Либы указал?
     
  8. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Satell
    "у меня в программе" - это где? Покажите как обьявлен прототип одной из этих функций в модуле, который её содержит, и в модуле, который её вызывает. Вероятно, в первом случае используется соглашение cdecl, а во втором - stdcall.
     
  9. mathio

    mathio New Member

    Публикаций:
    0
    Регистрация:
    16 июн 2007
    Сообщения:
    110
    Satell
    Это происходит из-за расхождений в описании функции при ее определении и объявлении. Как здесь уже упоминали во всем "виновата" конвенция вызова, которая родилась с появлением языков высокого уровня и по сути своей не применима к низкоуровневым языкам, типа ассемблера, где компилятор-транслятор сам _не_ строит исполнимый код, а лишь переводит соответствующие мнемоники в байт-код. Одной из главных задач трансляторов с ЯВУ является правильная генерация кода программы для случаев передачи управления внешним процедурам, например, посредством инструкции call и контроль за состоянием программного стека в эти моменты. Так как функции теперь умеют быть "перегруженными"(имя одно, а принимаемых параметров переменное кол-во), а также могут сами очищать со стека параметры, переданные им из вызывающей процедуры(эта фича также и для уменьшения размеров программ), нужно было придумать эффективный способ для правильной реализации этих механизмов во время связывания "объектников". Красивым решением оказалось - кодировать всю необходимую инф-ию через само имя вызываемой процедуры.

    Т.е. транслятор видя, например, объявление такой функции:
    Код (Text):
    1. // #define WINAPI __stdcall
    2.  
    3. extern int WINAPI foo( char *a );
    знает, что если далее в листинге ему встретится её вызов, ему нужно будет сгенерировать:
    1. Код по передаче одного параметра через стек
    2. Код по передаче управления на эту функцию
    А вот строить код для очистки параметра со стека после вызова уже не потребуется, т.к. стек уже будет выровнен вызываемой процедурой(__stdcall).
    Плюс к этому, в сгенерированный объектный файл он запишет правильно замангленное имя-метку, которое будет использоваться позже линкером в процессе связывания - _foo@4. И, соотв-но, линкер при окончательном построении программы в момент вычисления адреса метки будет искать такое и _только_ такое _foo@4 во всех указанных ему объектниках/либах.
    Т.е., как уже сказал Quantum, проблема скорее всего в __cdecl VS __stdcall :)