Re: __stdcall в dll функциях
От: okman Беларусь https://searchinform.ru/
Дата: 09.10.12 07:12
Оценка: 71 (4) +1
Здравствуйте, Loerosim, Вы писали:

L>Уважаемые гуру, подскажите, пожалуйста, почему если в dll объявить функцию через stdcall:

L>
L>extern "C" __declspec(dllexport) UINT __stdcall DllTestFunc();
L>

L>то эта функция не найдется при вызове GetProcAddress:
L>
L>typedef UINT (* __stdcall PointerDllTestFunc)();
L>HINSTANCE test_dll = LoadLibrary("test_dll.dll");
L>dll_test_func = (PointerDllTestFunc)GetProcAddress(test_dll, "DllTestFunc");      
L>

L>Если же убрать __stdcall, то всё будет хорошо...

Дело в том, что компилятор [VC++], чтобы отличать одну функцию от другой, — а C++ допускает
такую перегрузку, — хранит все имена в специальном внутреннем формате. Это называется декорацией
имен (name decoration или name mangling). Декорированное имя формируется в зависимости от имени функции,
от количества и типов ее аргументов, от типа соглашения о выховах (stdcall/cdecl/fastcall), а также от
того, используется ли C или C++.
Кое-какая полезная информация здесь — http://msdn.microsoft.com/en-us/library/deaxefa7(v=vs.100).aspx

До тех пор, пока функция не экспортируется, эта особенность нас не беспокоит, так как все вопросы
"стыковки" решаются компилятором. При экспорте функции, в зависимости от того, какой был выбран
способ экспорта, — def-файл или __declspec(dllexport), — в секцию экспорта попадает либо ее
оригинальное имя, либо уже декорированное. В первом случае GetProcAddress сможет найти функцию по
ее оригинальному имени, во втором — нет.

Тут еще вот какая особенность — функция C (не C++), имеющая соглашение о вызовах cdecl,
при экспорте будет иметь декорированное имя, совпадающее с оригинальным, и поэтому ее можно будет
находить посредством GetProcAddress, вне зависимости от типа экспорта. А компилятор VC++, если не
указано иное, считает все функции объявленными с соглашением cdecl. Как раз Ваш случай.

Вообще, тема не самая простая, поэтому набросаю ссылочек:
http://msdn.microsoft.com/en-us/library/x7kb4e2f(v=vs.100).aspx
http://msdn.microsoft.com/en-us/library/zkwh89ks(v=vs.100).aspx
http://msdn.microsoft.com/en-us/library/zxk0tw93(v=vs.100).aspx
http://msdn.microsoft.com/ru-ru/library/a90k134d(v=vs.100).aspx
http://msdn.microsoft.com/ru-ru/library/d91k01sh(v=vs.100).aspx
http://msdn.microsoft.com/ru-ru/library/900axts6(v=vs.90).aspx
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.