Отключение декорирования stdcall функций
Пишу программу, которая использует функции из этой библиотеки. При описании прототипа с использованием extern "C" и модификатора __stdcall компилятор декорирует имя функции - добавляет знак @ и число байт списка параметров. Например функция _WFM_Group_Control описывается как WFM_Group_Control@12, что выдает ошибку unresolved external symbol _WFM_Group_Control@12.
При использовании модификатора _cdecl все работает, но, естественно, накрывается стек.
Кто с этим сталкивался и как от этого избавится?
Имеется библиотека (DLL) с stdcall функциями. к ней .lib и .def
При описании прототипа с использованием extern "C" и модификатора __stdcall компилятор декорирует имя функции - добавляет знак @ и число байт списка параметров. Например функция _WFM_Group_Control описывается как WFM_Group_Control@12, что выдает ошибку unresolved external symbol _WFM_Group_Control@12.
При использовании модификатора _cdecl все работает, но, естественно, накрывается стек.
Кто с этим сталкивался и как от этого избавится?
Да, действительно VC искажает имена функций, которые экспортируются с соглашением __stdcall. Т.е. он ставит перед функцией подчёркивание а в конце @NumBytesParam. Что - бы этого избежать надо в def файл включить раздел EXPORTS т.е. -
EXPORTS
WFM_Group_Control
Я, правда, def файлами не пользуюсь, а делаю так:
#pragma comment (linker, "/export:WFM_Group_Control = _WFM_Group_Control@12")
Правда, экспортируются оба индентификатора одного и того же метода, но по моему, это ерунда.
Да, действительно VC искажает имена функций, которые экспортируются с соглашением __stdcall. Т.е. он ставит перед функцией подчёркивание а в конце @NumBytesParam. Что - бы этого избежать надо в def файл включить раздел EXPORTS т.е. -
EXPORTS
WFM_Group_Control
Я, правда, def файлами не пользуюсь, а делаю так:
#pragma comment (linker, "/export:WFM_Group_Control = _WFM_Group_Control@12")
Правда, экспортируются оба индентификатора одного и того же метода, но по моему, это ерунда.
да, я знаю что так можно экспортировать без декорирования. но дело в том, что мне нужно ИМПОРТИРОВАТЬ - использовать функции уже созданной DLL
да, я знаю что так можно экспортировать без декорирования. но дело в том, что мне нужно ИМПОРТИРОВАТЬ - использовать функции уже созданной DLL
Ок.
Значит, когда ты пишешь такой код, он у тебя не работает?
HMODULE h = ::LoadLibrary (/*Путь*/);
WFM_Group_Control = (void (__stdcall *)(/*параметры*/))GetProcAddress (h, "_WFM_Group_Control@12");
Если я что - то не правильно понял, то сорри.
Если ты пользуешь статическую линковку dll'ки, то не забудь подключить def файл к проекту, в Visual C++ достаточно просто вставить .def-файл в проект, он сам догадается, или добавить в опции линкёра /def:myfile.def.
Ок.
Значит, когда ты пишешь такой код, он у тебя не работает?
HMODULE h = ::LoadLibrary (/*Путь*/);
WFM_Group_Control = (void (__stdcall *)(/*параметры*/))GetProcAddress (h, "_WFM_Group_Control@12");
Если я что - то не правильно понял, то сорри.
Если ты пользуешь статическую линковку dll'ки, то не забудь подключить def файл к проекту, в Visual C++ достаточно просто вставить .def-файл в проект, он сам догадается, или добавить в опции линкёра /def:myfile.def.
дело в том, что .lib файл у меня самодельный и та же функция WFM_Group_Control определена там не как _WFM_Group_Control@12, а именно как WFM_Group_Control. отсюда ошибка unresolved external symbol. Поэтому нужно отключить декорирование, чтоб линковщик искал не _WFM_Group_Control@12, а WFM_Group_Control
дело в том, что .lib файл у меня самодельный и та же функция WFM_Group_Control определена там не как _WFM_Group_Control@12, а именно как WFM_Group_Control. отсюда ошибка unresolved external symbol. Поэтому нужно отключить декорирование, чтоб линковщик искал не _WFM_Group_Control@12, а WFM_Group_Control
Тогда извини, ничем помочь не могу, т.к. ни разу не линковал "чужую" dll'ку статически.
Я даже не знаю, каким образом ты умудрился создать .lib файл вручную. Если у тебя будет время, то напиши pls, как ты это сделал.
Тогда извини, ничем помочь не могу, т.к. ни разу не линковал "чужую" dll'ку статически.
Я даже не знаю, каким образом ты умудрился создать .lib файл вручную. Если у тебя будет время, то напиши pls, как ты это сделал.
да, долго я мучился, перед тем, как научился .lib делать...
для этого нужен файл от Borland С - impdef.exe (вообще в Borland'е с этим никаких проблем нет - там спец. утилита есть implib, только форматы .lib файлов различаются у MS и Borland). А дальше так:
impdef.exe library.def library.dll
lib.exe /DEF:library.def /out:library.lib
(lib.exe из MS VC++)
в принципе можно обойтись и без impdef.exe - просто вручную написать .def файл для .dll
да, долго я мучился, перед тем, как научился .lib делать...
для этого нужен файл от Borland С - impdef.exe (вообще в Borland'е с этим никаких проблем нет - там спец. утилита есть implib, только форматы .lib файлов различаются у MS и Borland). А дальше так:
impdef.exe library.def library.dll
lib.exe /DEF:library.def /out:library.lib
(lib.exe из MS VC++)
в принципе можно обойтись и без impdef.exe - просто вручную написать .def файл для .dll
Спасибо.
Очень интересно.
Поискал ещё инфы по этому вопросу.
Нашёл вот что:
Обязательно посмотри это обсуждение, по моему, там решается подобная твоей проблема.
http://www.rsdn.ru/Forum/Message.aspx?mid=292614#292614
Посмотри здесь, может найдёшь ещё кое что интересное.
http://www.rsdn.ru/search/?page=1&mode=rank&q=lib.exe
Спасибо.
Очень интересно.
Поискал ещё инфы по этому вопросу.
Нашёл вот что:
Обязательно посмотри это обсуждение, по моему, там решается подобная твоей проблема.
http://www.rsdn.ru/Forum/Message.aspx?mid=292614#292614
Посмотри здесь, может найдёшь ещё кое что интересное.
http://www.rsdn.ru/search/?page=1&mode=rank&q=lib.exe
спасибо
проблему "решил" таким способом: отредактировал полученный .def файл, добавив в конец импортируемых функций @NumBytesParam и создал .lib заново. Извращение, конечно, особенно если функций штук 100, но, делать нечего...