Пытаюсь создать простенькую DLL в VisualC++.
Проблема в том, что при вызове, приложение не находит точек входа в DLL (не может получить адреса функций).
Если же в библиотеке функции без параметров, то все работает. Подозреваю, что это как-то связано с механизмом передачи параметров при вызове (или с несоответствием этих механизмов в DLL и вызывающей программе).
Кто сталкивался с такой проблемой или знает в чем может быть дело - подскажите.
Если кому не в лом покопаться в исходниках, то библиотеку и вызывающую программу выложу здксь.
Если у кого есть работающий пример DLL с вызывающей программой (только что-нибудь по-проще), то вышлите мне на мыло, плз.
[Ответ]
Чтобы компилятор генерировал недекорированные имена функций, использую модификатор __cdecl:
extern "C" __declspec(dllexport) int __cdecl func(int,int)
{
return 0;
}
иначе в таблице символов получишь что-то вроде _func@8
[Ответ]
RomanPshenichny 16:23 08.07.2003
Сообщение от : Первоначальное сообщение от Fisher Чтобы компилятор генерировал недекорированные имена функций, использую модификатор __cdecl:
extern "C" __declspec(dllexport) int __cdecl func(int,int)
{
return 0;
}
иначе в таблице символов получишь что-то вроде _func@8
Вообще-то, недекорированные имена делает именно extern "C". А __cdecl это всего лишь соглашение о обратном помещении параметров в стек и то, что вызывающая процедура очищает стек.
А декорированное имя или нет для эскпорта/импорта DLL не имеет никакого значения.
PS. А как же по твоему сделать эспорт целого класса из DLL?
Неужели на extern "C"? [Ответ]
Fisher 18:22 08.07.2003
Сообщение от :
[i]Вообще-то, недекорированные имена делает именно extern "C".
extern "C" указывает на то, что объект/функция имеют C-линковку, т.к. в С++ по умолчанию используется С++-линковка (см. Стандарт 7.5).
Сообщение от :
А __cdecl это всего лишь соглашение о обратном помещении параметров в стек и то, что вызывающая процедура очищает стек.
Совершенно верно. Более того, если посмотреть MSDN, можно прочесть:
"The form of decoration for a C function depends on the calling convention used in its declaration, as shown below.
Calling Convention Decoration
__cdecl (the default) Leading underscore (_)
__stdcall Leading underscore (_) and a trailing at sign (@) followed by a number representing the number of bytes in the parameter list
__fastcall Same as __stdcall, but prepended by an at sign instead of an underscore "
Сообщение от :
А декорированное имя или нет для эскпорта/импорта DLL не имеет никакого значения.
Смотря как использовать функцию. Если через import library, то линковщик сам установит связь (если конечно он знаком с форматом декорирования), но если использовать GetProcAddress, то нужно указывать название функции, которое она получила у компилятора, а не у программиста.
Сообщение от :
PS. А как же по твоему сделать эспорт целого класса из DLL?
Все зависит от средства разработки. В MSVC достаточно указать атрибут __declspec(dllexport).
Сообщение от :
Неужели на extern "C"? [/B]
Спецификация линковки используется с функциональными типами, именами функций и именами переменных.
[Ответ]
Zhenek2002 10:23 09.07.2003
RomanPshenichnyFisher Спасибо. Действительно у функций были имена вроде _func@8, поэтому GetProcAddress их не находила (я использовал __stdcall).
Тогда возникает другой вопрос: мне нужно, чтобы функции в библиотеке быть описаны с директивой __stdcall, чтобы вызывающая программа не заботилась об очистке стека (библиотека будет вызываться из VB и еще нескольких довольно экзотических языков - MSM-Workstation и Cache). А можно как-нибудь сделать так, чтобы при этом имена функций не менялись или хотя бы, чтоб не пришлось подсчитывать объем параметров в байтах для того, чтобы угадать имя функции.
[Ответ]
Fisher 11:23 09.07.2003
Сообщение от :
Тогда возникает другой вопрос: мне нужно, чтобы функции в библиотеке быть описаны с директивой __stdcall, чтобы вызывающая программа не заботилась об очистке стека (библиотека будет вызываться из VB и еще нескольких довольно экзотических языков - MSM-Workstation и Cache).
Вызывающая программа (точнее программист) и не заботится об очистке стека - это делает компилятор.
Сообщение от :
А можно как-нибудь сделать так, чтобы при этом имена функций не менялись или хотя бы, чтоб не пришлось подсчитывать объем параметров в байтах для того, чтобы угадать имя функции.
С компилятором от MS этого сделать нельзя. Это и не нужно, если на языке клиента можно описать вызываемую функцию с требуемым соглашением о вызове.
[Ответ]
is 20:45 09.07.2003
Присоединяюсь к Роману и Fisher'у.
Кроме того, рекомендую Вам использовать def файл.
За подробностями позвольте Вас отправить в msdn по адресу
ms-help://MS.VSCC/MS.MSDNVS/vccore/html/_core_Export_from_a_DLL_Using_..DEF_Files.htm
P.S. Господа программеры ни у кого Visual Studio 2003 не найдется? Очень уж хочется попробовать С++ компилятор и насколько он близок к стандарту.
[Ответ]
LSL 21:30 09.07.2003
is P.S. Господа программеры ни у кого Visual Studio 2003 не найдется? Очень уж хочется попробовать С++ компилятор и насколько он близок к стандарту.
А в студии 7.1(2003) разве другой компилятор в отличии от 7.0
[Ответ]
is 21:54 09.07.2003
LSL Да, компилятор С++ другой. Обещали приблизиться к стандарту на 98%. Плюс .net фреймворк v.1.1.
А вот я не понял: как это VS2003 на 8 компактах? Слышал, что по подписке MSDN Universal она занимает 716 или 724 Мб в зип архиве и msdn они на этот раз не включали в поставку. Или в ентерпрайз аркитект все есть?
[Ответ]
Zhenek2002 12:20 11.07.2003
is Спасибо. Попробовал с def-файлом и все получилось.
[Ответ]
Fisher 16:14 11.07.2003
Можно и без .DEF файла обойтись, сделав линковщику явное указание в .cpp файле:
#pragma comment(linker, "/export:func=_func@8")
, но это ведь не избавляет от необходимости корректного объявления функции на языке клиента.
Fisher добавил [date]1057929538[/date]:
Сообщение от :
А вот я не понял: как это VS2003 на 8 компактах?
То была не шутка Комплект, купленный на Митино, состоит из 8 CD, их содержимое я перечислял.
Сообщение от :
Или в ентерпрайз аркитект все есть?