Похоже я столкнулся с багом линкера, помогите.

Тема в разделе "LANGS.C", создана пользователем mad_fat_rabbit, 10 дек 2007.

  1. mad_fat_rabbit

    mad_fat_rabbit New Member

    Публикаций:
    0
    Регистрация:
    22 май 2007
    Сообщения:
    4
    Объясняю ситуацию. Есть у меня либа статическая, которой пользуюсь давно, и проблем с ней не было. Какое-то время назад я стал рефакторить ее код и всех связанных с ней проектов - загнал в солюшн (VC 2005) сначала ее, а затем стал потихоньку подключать все остальное. Месяца три шло все хорошо, но в какой-то момент я подключил проект, который стал использовать модуль консоли.

    Код (Text):
    1. ...
    2. void CON_Init();
    3. void CON_Shutdown();
    4.  
    5. void CON_Show(bbool show);
    6. void CON_Toggle();
    7. ...
    8. bbool CON_Execute(bbool restricted, char* fmt, ... );
    9. bbool CON_ExecuteFile(const char* fileName);
    10. bbool CON_SaveVars(const char* fileName);
    11. char* CON_MatchCommand(char* nameStart, uint32 nameCmpLen, uint32 matchSkipCount);
    12.  
    13. void CON_Printf(const char* fmt, ... );
    14. uint32 CON_GetNumPrintLines();
    15. char* CON_GetPrintLine(uint32 index);
    16. void CON_SetPrintCallback(void (*callback)(const char*));
    17. ...
    Все функции линкуются нормально, кроме двух!

    Код (Text):
    1. Linking...
    2. State.obj : error LNK2019: unresolved external symbol "unsigned char __cdecl CON_Execute(unsigned char,char *,...)" (?CON_Execute@@YAEEPADZZ) referenced in function "void __cdecl TimeScale_confunc_body(class CConVar *,int,char * *)" (?TimeScale_confunc_body@@YAXPAVCConVar@@HPAPAD@Z)
    3. tked.lib(con_main.obj) : error LNK2001: unresolved external symbol "unsigned char __cdecl CON_Execute(unsigned char,char *,...)" (?CON_Execute@@YAEEPADZZ)
    4. tked.lib(con_win.obj) : error LNK2001: unresolved external symbol "unsigned char __cdecl CON_Execute(unsigned char,char *,...)" (?CON_Execute@@YAEEPADZZ)
    5. tked.lib(con_win.obj) : error LNK2019: unresolved external symbol "void __cdecl CON_SetPrintCallback(void (__cdecl*)(char const *))" (?CON_SetPrintCallback@@YAXP6AXPBD@Z@Z) referenced in function "void __cdecl CONW_Init(void)" (?CONW_Init@@YAXXZ)
    Я и так уже, и эдак, никак. Уже и из либы модули вытащил, подключил их напрямую в проект - бестолку. Переименовывал эти функции - бестолку. Заколдованные какие-то. Только когда я коменчу вызовы этих функций (CON_Execute, CON_SetPrintCallback) все собирается. В чем дело - непонятно.
    У либы есть особенность - она целиком на C, кроме модулей консоли (С++) - может в этом проблема? Но почему тогда на другие функции не ругается? Непонятно что делать, может есть какие-то мысли?
     
  2. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    mad_fat_rabbit
    Чтобы не гадать, проще всего посмотреть манглированные имена этих ф-ций в либе.
    Если нужно, могу глянуть сам - выложи либу или объектники, содержащие эти ф-ции.
     
  3. mad_fat_rabbit

    mad_fat_rabbit New Member

    Публикаций:
    0
    Регистрация:
    22 май 2007
    Сообщения:
    4
    Вот что показала IDA:
    Код (Text):
    1. ; void __cdecl CON_SetPrintCallback(void (__cdecl *)(char *))
    2. public ?CON_SetPrintCallback@@YAXP6AXPAD@Z@Z
    3. ?CON_SetPrintCallback@@YAXP6AXPAD@Z@Z proc near
    4.  
    5. ; unsigned char __cdecl CON_Execute(unsigned char, char const *, ...)
    6. public ?CON_Execute@@YAEEPBDZZ
    7. ?CON_Execute@@YAEEPBDZZ proc near
    объектник выложил если что на http://www.games4free.ru/files/con_main.obj
     
  4. mad_fat_rabbit

    mad_fat_rabbit New Member

    Публикаций:
    0
    Регистрация:
    22 май 2007
    Сообщения:
    4
    Продолжаю свои мучения )
    Да, похоже дело в манглировании функций. Обратил внимание (green, спасибо), что в ошибках показываются функции
    Код (Text):
    1. CON_Execute@@YAEEPADZZ
    2. CON_SetPrintCallback@@YAXP6AXPBD@Z@Z
    а IDA говорит что там есть функции
    Код (Text):
    1. CON_Execute@@YAEEPBDZZ
    2. CON_SetPrintCallback@@YAXP6AXPAD@Z@Z
    выходит что в именах поменялись местами части имен PBD и PAD. Чудеса какие-то...
     
  5. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    mad_fat_rabbit
    Ошибка в том, что эти ф-ции у тебя декларируются и определяются по разному.
    Декларации:

    bbool CON_Execute(bbool restricted, char* fmt, ... );
    void CON_SetPrintCallback(void (*callback)(const char*));


    Определения:

    bbool CON_Execute(bbool restricted, const char* fmt, ... )
    {
    ...
    }
    void CON_SetPrintCallback(void (*callback)(char*))
    {
    ...
    }
     
  6. mad_fat_rabbit

    mad_fat_rabbit New Member

    Публикаций:
    0
    Регистрация:
    22 май 2007
    Сообщения:
    4
    Вот это я на рефакторил... Спасибо green, извини что отвлек таким тупняком. Я от безысходности нарыл в wine восстановленные исходники функции __unDNameEx из msvcrt.dll и на основе ее написал тулзу - которая мне показала, что за баг в линкере :)
    Выкладываю ее с сорсами, может кому пригодится: http://www.games4free.ru/files/msmangle.zip.
    Тема закрыта.