Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Работа с Dll. Как?

4.2K
07 июля 2004 года
mmr
11 / / 30.11.2003
Хочу занести пару функций в DLL, но не знаю как эта самая DLL пишется. Нашел пару примеров, но прога вылетает из-за недопустимой операции. Просьба: пришлите пример хотя-бы самой простой DLL'ки с одной экспортируемой функцией, а также необходим кусок кода основной программы, который подключал бы функции из библиотеки. [mmr@km.ru]
527
07 июля 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by mmr
Хочу занести пару функций в DLL, но не знаю как эта самая DLL пишется. Нашел пару примеров, но прога вылетает из-за недопустимой операции. Просьба: пришлите пример хотя-бы самой простой DLL'ки с одной экспортируемой функцией, а также необходим кусок кода основной программы, который подключал бы функции из библиотеки. [mmr@km.ru]


Здрассте, приехали. Там даже мастер по созданию DLL пример экспортирования. А чтобы вызывать включаешь header и вызваешь ее как обычно.

4.2K
10 июля 2004 года
mmr
11 / / 30.11.2003
Цитата:
Originally posted by pavor

Здрассте, приехали. Там даже мастер по созданию DLL пример экспортирования. А чтобы вызывать включаешь header и вызваешь ее как обычно.


Включая header, получим статически подключенную библиотеку. А я хочу подключить ее динамически, функцией LoadLibrary. Только вот прога вылетает. Потому и прошу небольшой, но рабочий исходник.

527
10 июля 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by mmr

Включая header, получим статически подключенную библиотеку. А я хочу подключить ее динамически, функцией LoadLibrary. Только вот прога вылетает. Потому и прошу небольшой, но рабочий исходник.


Это называется не статически, ну да ладно.
Вопросы:
1)как делаешь?
2)где выдает ошибку?
3)объявил ли в .def файле или не знал об этом

487
11 июля 2004 года
ddnh_bc
301 / / 16.09.2003
Цитата:
Originally posted by pavor

Это называется не статически, ну да ладно.
Вопросы:
1)как делаешь?
2)где выдает ошибку?
3)объявил ли в .def файле или не знал об этом



Ну помимо .def файла еще можно использовать __declspec(dllexport).

Если коротко:
Чтобы тебе сделать ДЛЛ - необходимо:
1. Обязательно объявить DllMain - причем вернуть на выходе из нее верное значение - (кажется TRUE) - ежели память не изменяет.
2. Корректно написать функции и экспортировать их либо через .def файл (ИМХО в ряде случаев удобнее), либо через __declspec(dllexport) - что проще, если не хочешь возиться с .DEF файлом.

Вот собсно и все.

4.2K
11 июля 2004 года
mmr
11 / / 30.11.2003
В тексте самой библиотеки пишу это:

Код:
#include <windows.h>

#define EXPORT extern "C" __declspec (dllexport)

EXPORT int CALLBACK SomeFunc(char *str);

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

EXPORT int CALLBACK SomeFunc(char *str)
{   MessageBox(NULL, str, "From DLL", MB_OK);
   
    return 1;
}



Все это без ошибок компилируется в файл Dll_C.dll. Теперь текст самой проги:

Код:
#include <windows.h>

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

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

    if((hMyDll = LoadLibrary("Dll_C")) == NULL) return 1;

    PFN_MyFunction pfnFunc;
    int iCode;

    pfnFunc = (PFN_MyFunction)GetProcAddress(hMyDll, "SomeFunc");
    iCode = (*pfnFunc)("Hello");

    FreeLibrary(hMyDll);
   
    return 0;
}


Компиляция проходит опять без ошибок, но при запуске - недопустимая операция. Сама библиотека и исполняемый файл лежат в одной папке.
527
11 июля 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by mmr
В тексте самой библиотеки пишу это:

Код:
#include <windows.h>

#define EXPORT extern "C" __declspec (dllexport)

EXPORT int CALLBACK SomeFunc(char *str);

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

EXPORT int CALLBACK SomeFunc(char *str)
{   MessageBox(NULL, str, "From DLL", MB_OK);
   
    return 1;
}



Все это без ошибок компилируется в файл Dll_C.dll. Теперь текст самой проги:

Код:
#include <windows.h>

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

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

    if((hMyDll = LoadLibrary("Dll_C")) == NULL) return 1;

    PFN_MyFunction pfnFunc;
    int iCode;

    pfnFunc = (PFN_MyFunction)GetProcAddress(hMyDll, "SomeFunc");
    iCode = (*pfnFunc)("Hello");

    FreeLibrary(hMyDll);
   
    return 0;
}


Компиляция проходит опять без ошибок, но при запуске - недопустимая операция. Сама библиотека и исполняемый файл лежат в одной папке.


Напиши def файл

3
12 июля 2004 года
Green
4.8K / / 20.01.2000
Я кое-что подправил, посмотри:
Код:
#include <windows.h>

#define EXPORT extern "C" __declspec (dllexport)

EXPORT int SomeFunc(char *str); // без CALLBACK

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdReason, PVOID pvReserved) // Правильнее BOOL, хотя это не критично
{  
    return TRUE;  // Тоже не критично
}

EXPORT int SomeFunc(char *str)  // без CALLBACK
{  
    MessageBox(NULL, str, "From DLL", MB_OK);
    return 1;
}


Код:
#include <windows.h>

typedef int (*PFN_MyFunction)(char *);  // здесь без WINAPI

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{  
    HINSTANCE hMyDll = LoadLibrary("Dll_C");
    if(!hMyDll) return 1;

    PFN_MyFunction pfnFunc = (PFN_MyFunction)GetProcAddress(hMyDll, "SomeFunc");

    int iCode = pfnFunc("Hello"); // Здесь не надо явно разыменовывать указатель

    FreeLibrary(hMyDll);   
    return 0;
}


Для pavor:
Ну и зачем здесь def-файл?
527
12 июля 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by Green
Я кое-что подправил, посмотри:
Код:
#include <windows.h>

#define EXPORT extern "C" __declspec (dllexport)

EXPORT int SomeFunc(char *str); // без CALLBACK

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdReason, PVOID pvReserved) // Правильнее BOOL, хотя это не критично
{  
    return TRUE;  // Тоже не критично
}

EXPORT int SomeFunc(char *str)  // без CALLBACK
{  
    MessageBox(NULL, str, "From DLL", MB_OK);
    return 1;
}


Код:
#include <windows.h>

typedef int (*PFN_MyFunction)(char *);  // здесь без WINAPI

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{  
    HINSTANCE hMyDll = LoadLibrary("Dll_C");
    if(!hMyDll) return 1;

    PFN_MyFunction pfnFunc = (PFN_MyFunction)GetProcAddress(hMyDll, "SomeFunc");

    int iCode = pfnFunc("Hello"); // Здесь не надо явно разыменовывать указатель

    FreeLibrary(hMyDll);   
    return 0;
}


Для pavor:
Ну и зачем здесь def-файл?


CALLBACK и WINAPI = __stdcall

3
12 июля 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by pavor

CALLBACK и WINAPI = __stdcall



Кто тебе такую глупость сказал?
Ты не задумывался, почему бы тогда не писать просто __stdcall ?
Это макрос и раскрываться он может в зависимости от параметров компиляции.

Читаем MSDN:

Цитата:

CALLBACK Calling convention for callback functions.

WINAPI Calling convention for system functions.



К предыдущему посту:
так зачем тебе понадобился .def ?

527
12 июля 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by Green


Кто тебе такую глупость сказал?
Ты не задумывался, почему бы тогда не писать просто __stdcall ?
Это макрос и раскрываться он может в зависимости от параметров компиляции.

Читаем MSDN:


К предыдущему посту:
так зачем тебе понадобился .def ?


Просто делал все время через .def и не заморачивался. Поэтому не могу посоветовать насчет __declspec(dllexport).

4.2K
16 июля 2004 года
mmr
11 / / 30.11.2003
Поправки BioUnit'а принесли свои плоды. Все работает. Скорее всего, не надо было разыменовывать указатель при вызове функции из библиотеки, в этом и была ошибка.
6.3K
13 августа 2004 года
Denri
43 / / 12.08.2004
Цитата:
Originally posted by mmr
Поправки BioUnit'а принесли свои плоды. Все работает. Скорее всего, не надо было разыменовывать указатель при вызове функции из библиотеки, в этом и была ошибка.


В догонку. Бывает много проблем с именами функций в dll - вредит декорирование имён. Например, функция __stdcall f(int, int) в конце концов будет называться _f@8, а если не напишешь extern "C", то имена бубут ещё страшнее. Чтобы этого не происходило, можно не писать в тексте программы директив __declspec(dllexport), но написать .def-файл - тогда декорирования не будет.

527
14 августа 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by Denri

В догонку. Бывает много проблем с именами функций в dll - вредит декорирование имён. Например, функция __stdcall f(int, int) в конце концов будет называться _f@8, а если не напишешь extern "C", то имена бубут ещё страшнее. Чтобы этого не происходило, можно не писать в тексте программы директив __declspec(dllexport), но написать .def-файл - тогда декорирования не будет.


отож8)

6.3K
09 сентября 2004 года
triclosan
19 / / 11.08.2004
Green
Цитата:
Originally posted by Green
Я кое-что подправил, посмотри:
Код:
#include <windows.h>

#define EXPORT extern "C" __declspec (dllexport)

EXPORT int SomeFunc(char *str); // без CALLBACK

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdReason, PVOID pvReserved) // Правильнее BOOL, хотя это не критично
{  
    return TRUE;  // Тоже не критично
}

EXPORT int SomeFunc(char *str)  // без CALLBACK
{  
    MessageBox(NULL, str, "From DLL", MB_OK);
    return 1;
}


Код:
#include <windows.h>

typedef int (*PFN_MyFunction)(char *);  // здесь без WINAPI

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{  
    HINSTANCE hMyDll = LoadLibrary("Dll_C");
    if(!hMyDll) return 1;

    PFN_MyFunction pfnFunc = (PFN_MyFunction)GetProcAddress(hMyDll, "SomeFunc");

    int iCode = pfnFunc("Hello"); // Здесь не надо явно разыменовывать указатель

    FreeLibrary(hMyDll);   
    return 0;
}




Я пробовал компилить пример - dll OK, а программа, что dll подключает:

Код:
--------------------Configuration: dll_load2 - Win32 Debug--------------------
Compiling...
StdAfx.cpp
Compiling...
dll_load2.cpp
Linking...
LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Debug/dll_load2.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

dll_load2.exe - 2 error(s), 0 warning(s)


З.Ы. VC++ 6
3
10 сентября 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by triclosan
Green
LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
[/CODE]



Если ты создаешь консольное приложение, то в коде должна быть функция main, если ты создаешь оконное приложение, то - WinMain.

6.3K
11 сентября 2004 года
triclosan
19 / / 11.08.2004
Цитата:
Originally posted by Green


Если ты создаешь консольное приложение, то в коде должна быть функция main, если ты создаешь оконное приложение, то - WinMain.



Заменил WinMain на main (у меня консоль), все компилируется, но Длл не грузится:( .
Это моя первая попытка создать такого рода приложение, поэтому возможно что-то перепутал. К примеру, "Dll_C" это общий стандарт или имя dll-файла (dll.dll получаетмся в таком случае:-?)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог