Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / C++ Новый топик    Ответить
 Почему не экспортируется функция из dll без def-файла?  [new]
Guilty
Member

Откуда: Ярославль
Сообщений: 149
(компилятор Visual C++)
В MSDN сказано, что существуют два способа экспорта функций из dll:
- используя ключевое слово __declspec(dllexport) при объявлении функции в dll;
- либо с помощью файла def.
Однако, я столкнулся с проблемой: у меня без файла def функция не экспортируется даже при использовании первого способа.

Пример (из какого-то источника).
mydll.h

#define EXPORT __declspec(dllexport)
EXPORT int CALLBACK MyFunction(char* str);

mydll.cpp

#include <windows.h>
#include "mydll.h"

int WINAPI DllMain(HINSTANCE hInstance, DWORD fdReason, PVOID pvReserved)
{
return TRUE;
};

EXPORT int CALLBACK MyFunction(char *str)
{
Beep(500, 100);
MessageBox(NULL, str, "Function from DLL", MB_OK);
return 1;
}

myapp.cpp

#include <windows.h >

typedef int (WINAPI *PFN_MyFunction) (char *);

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HINSTANCE hMyDll;

if((hMyDll = ::LoadLibrary("mydll"))==NULL)
{
MessageBox(NULL, "Cannot load dll!", " ", MB_OK);
return 1;
}

PFN_MyFunction pfnMyFunction;

pfnMyFunction = (PFN_MyFunction)::GetProcAddress(hMyDll, "MyFunction");

try
{
int iCode = (*pfnMyFunction)("Successful execution of dll function!");
}
catch(...)
{
MessageBox(NULL, "Error!", " ", MB_OK);
}
::FreeLibrary(hMyDll);

return 0;
}


Оба проекта (библиотечный и приложения прекрасно построились), однако при выполнении приложения myapp возникает исключение в блоке try во время попытки вызвать функцию из dll. При пошаговой отладке видно, что при получения адреса нужной функции из dll, указатель становится равным нулю. Однако если добавить в проект dll файл def следующего содержания:

mydll.def

LIBRARY mydll

EXPORTS
MyFunction @1

все становится на свои места и функция нормально вызывается из программы myapp хоть по имени, хоть по номеру функции.
В чем тут, дело? ведь в MSDN явно сказано: If you use __declspec(dllexport), you do not need a .DEF file for exports.
18 янв 04, 18:38    [496136]     Ответить | Цитировать Сообщить модератору
 Re: Почему не экспортируется функция из dll без def-файла?  [new]
funikovyuri
Member

Откуда: Симферополь
Сообщений: 4047
PFN_MyFunction pfnMyFunction;


pfnMyFunction = (PFN_MyFunction)::GetProcAddress(hMyDll, "MyFunction");


А что это значит?
19 янв 04, 09:56    [496408]     Ответить | Цитировать Сообщить модератору
 Re: Почему не экспортируется функция из dll без def-файла?  [new]
CEMb
Member

Откуда: public T{};
Сообщений: 1943
автор
- используя ключевое слово __declspec(dllexport) при объявлении функции в dll;


Соответственно, там где импортируешь, надо сделать описание как:

__declspec(dllimport)

Кстати, когда даже в VC создаёшь проект (не помню какой) для длл-ки. Она(VS) расписывает три експортируемые вещи: переменную, функцию и класс.
При этом заводится(типа)

#define MY_EXPORT

и потом в заголовке
#ifdef MY_EXPORT
#define _import_def __declspec(dllexport)
#else
#define _import_def __declspec(dllimport)
#endif

Таким образом, можно этот заголовочный файл использовать как в самом проекте, так и в проектах для имопорта вещей из него.

Попровьте, если я чего не так сказал :)
19 янв 04, 10:24    [496450]     Ответить | Цитировать Сообщить модератору
 Re: Почему не экспортируется функция из dll без def-файла?  [new]
funikovyuri
Member

Откуда: Симферополь
Сообщений: 4047
CEMb

Сказал все так - только вот Guilty использует динамическое связывание а dllimport - статическое
19 янв 04, 10:47    [496488]     Ответить | Цитировать Сообщить модератору
 Re: Почему не экспортируется функция из dll без def-файла?  [new]
maratka
Member

Откуда: Казань
Сообщений: 214
думаю, дело тут совсем не в методе линковки, а в т.н. naming decoration т.е.,
CALLBACK означает FAR PASCAL, следовательно имя ф-ии экспортируется
без DEF-файла как _MyFunction@4 (и GetProcAddress не прокатывает), а с
этим файло - как MyFunction и все работает.
2 Guilty: оба случая необходимо проверить с помощью Dependency Walker конечно или подобной.
imho. удачи.
19 янв 04, 14:27    [497092]     Ответить | Цитировать Сообщить модератору
 Re: Почему не экспортируется функция из dll без def-файла?  [new]
Ой Вэй
Member

Откуда: Харьков
Сообщений: 581
Я согласен с funikovyuri.
Скажу подробнее:
1) для использования LoadLibrary/GetProcAddress запись в def-файле необходима;
2) без записи в def-файле можно вызвать dllexport функцию, только если слинковать exe с lib-файлом dll.
19 янв 04, 15:36    [497334]     Ответить | Цитировать Сообщить модератору
 Re: Почему не экспортируется функция из dll без def-файла?  [new]
Guilty
Member

Откуда: Ярославль
Сообщений: 149
2 funikovyuri
автор

>PFN_MyFunction pfnMyFunction;
>pfnMyFunction = (PFN_MyFunction)::GetProcAddress(hMyDll, "MyFunction");

>А что это значит?

1 строка: Объявление указателя на функцию
2 строка: получение адреса функции и приведение к объвленному указателю.

2 ALL
Похоже все дело, как правильно заметил maratka (большое спасибо ему за это), в декорировании имени функции. Компилятор по разному декорирует имена при компиляции C модулей и C++ модулей. (CALLBACK перед функцией я вообще убрал) Пример:

1) берем проект mydll с двумя файлами в нем mydll.h и mydll.cpp (файл mydll.def -

выбрасываем), строим, потом смотрим, что внутри mydll.dll

dumpbin /exports mydll.dll

получаем имя функции ?MyFunction@@YAHPAD@Z
2) берем тот же проект, однако файл mydll.cpp заменяем точно таким же mydll.c (файл mydll.def по прежнему отсутствует), строим, смотрим:

dumpbin /exports mydll.dll

получаем имя функции MyFunction

Теперь функция нормально вызывается из приложения myapp.exe по имени MyFunction.

2 Ой Вэй
Так что похоже файл def все-таки не обязателен для динамического использования функций из dll? ;)
20 янв 04, 00:00    [497989]     Ответить | Цитировать Сообщить модератору
 Re: Почему не экспортируется функция из dll без def-файла?  [new]
CEMb
Member

Откуда: public T{};
Сообщений: 1943
Не понял...
Декларация как FAR ведёт к экспорту функции?
20 янв 04, 10:39    [498307]     Ответить | Цитировать Сообщить модератору
 Re: Почему не экспортируется функция из dll без def-файла?  [new]
maratka
Member

Откуда: Казань
Сообщений: 214
действительно, я немного поторопился, если ф-я не определена как extern "C",
то линкер генерирует расширенное имя ф-ии, типа ?MyFunction@@YAHPAD@Z, а для *.с-файлов определен язык С по умолчанию. так что я всегда определяю экспортируемые ф-ии как extern "C".
FAR в вин32 устарел и ни чему не соответствует.
20 янв 04, 11:19    [498461]     Ответить | Цитировать Сообщить модератору
 Re: Почему не экспортируется функция из dll без def-файла?  [new]
CEMb
Member

Откуда: public T{};
Сообщений: 1943
Ясно, спасибо :)

Одним типом файлов меньше :)
21 янв 04, 10:15    [500221]     Ответить | Цитировать Сообщить модератору
Все форумы / C++ Ответить