Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Динамический импорт DLL в MinGW


Автор: jhonyxakep 27.2.2010, 15:32
 smile Опять ЙА....
Написал тестовую длл (функция string test(void); тупо возвращает строку "test,test":))
Решил динамически её импортировать из длл:
Код

typedef double (*importFunction)(void);

int main(int argc, char *argv[])
{
    importFunction test;
     //double result;
 
     /* Çàãðóæàåì DLL â ïàìÿòü */
     HINSTANCE hinstLib = LoadLibrary("dllka.dll");
     if (hinstLib == NULL) {
         printf("ERROR: unable to load DLL\n");
         return 1;
     }
 
     /* Ïîëó÷àåì óêàçàòåëü íà ôóíêöèþ */
     test = (importFunction)GetProcAddress(hinstLib, "test");
     if (test == NULL) {
         printf("ERROR: unable to find DLL function\n");
         return 1;
     }
 
     /* Âûçûâàåì ôóíêöèþ ÷åðåç óêàçàòåëü */
     cout << test() <<endl;
 
     /*
      * Âûãðóæàåì DLL (â ïðèíöèïå, ýòî áóäåò ñäåëàíî
      * àâòîìàòè÷åñêè ïðè âûõîäå èç ïðîãðàììû)
      */
     FreeLibrary(hinstLib);
    
    
    system("PAUSE");
    return EXIT_SUCCESS;
}

(код взят с инета)

в результате я получаю фатальную ошибку (в прикреплении)

Кстати это вторая моя попытка использовать динамическое подключение, и всегда такой результат.

ЗЫ Юзаю extern "C" перед экспортом.

Автор: borisbn 27.2.2010, 16:17
ты определись, что возвращает функция: строку или double.
Если в самой dll-ке строку, то понятно, почему не работает

Автор: ThisIsSparta 27.2.2010, 19:28
Если extern "C", то имя функции должно быть примерно таким: "_test@0". 
Попробуй так:
Код
test = (importFunction)GetProcAddress(hinstLib, "_test@0");

EDIT:
в dll функция должна быть проэкспортирована:
Код
extern "C" string void __declspec(dllexport) test(void);

Автор: borisbn 28.2.2010, 00:34
ThisIsSparta, extern "C" как раз указывает, что функция не должна декорироваться
а твой пример:
extern "C" string void ...
не будет компилироваться

Автор: ThisIsSparta 28.2.2010, 01:25
Хм. Пример-то скомпилировался, но с предупреждением "'identifier1' has C-linkage specified, but returns UDT 'identifier2' which is incompatible with C ".
Мда... Действительно имя задается как есть, но... Почему я ошибся? Просто недавно тоже экспериментировал с линковками, но экспериментировал с __stdcall-функциями. В __cdecl все происходит так, как Вы сказали - имя не декодируется. А что будет, если попробовать вот такую функцию?
Код
extern "C" void  __declspec(dllexport) __stdcall test(int x, int x1)
{
}

Она будет проэкспортирована с именем:
Код
_test@8

 8 - это выравнивание стека. Хотя сильно во всю эту радость не влазил. Возможно, это просто особенности линкера MSVC...

Автор: jhonyxakep 28.2.2010, 02:30
Цитата(borisbn @  27.2.2010,  16:17 Найти цитируемый пост)
ты определись, что возвращает функция: строку или double.

 smile Ой, сорь, действительно, не знаю как так мог ошибится...

ThisIsSparta, действительно я для того и ставил extern "C" что бы функция была более менее красивого вида.

 smile А так все запахало!!!!

 smile Досадная ошибка с double.

Добавлено через 1 минуту и 26 секунд
Цитата(ThisIsSparta @  27.2.2010,  19:28 Найти цитируемый пост)
в dll функция должна быть проэкспортирована:код C++1:extern "C" string void __declspec(dllexport) test(void);

А я что, не экспортирую???smile
Код

#include <windows.h>
#include <iostream.h>

using namespace std;

extern "C" __declspec (dllexport) string test(void);
string test(void)
{
return "testing 123";
}

BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{

    return TRUE;
}


Автор: jhonyxakep 28.2.2010, 02:45
Цитата(ThisIsSparta @  28.2.2010,  01:25 Найти цитируемый пост)
_test@8

по моему это все таки линковка в стиле C++. А вот что дают названия функций в таком стиле?

Автор: borisbn 28.2.2010, 06:48
ThisIsSparta, Имя __cdecl и __stdcall функций, объявленных в msvc как extern "C" отличаются только подчеркиванием в начале

jhonyxakep, очень не советую экспортировать из длл-ки stl-классы, т.к. они будут вылетать (и это в лучшем случае), если ты будешь использовать их в программе, откомпилированной другим компилятором или даже тем же компилятором, но с другой версией stl

Автор: xvr 2.3.2010, 17:56
Цитата(jhonyxakep @ 28.2.2010,  02:45)
Цитата(ThisIsSparta @  28.2.2010,  01:25 Найти цитируемый пост)
_test@8

по моему это все таки линковка в стиле C++. 

Это С (__stdcall), а 8 - это размер аргументов на стеке. 
Цитата

А вот что дают названия функций в таком стиле?
Дает некоторую гарантию, что и вызывающая и вызываемая функция считают размер аргументов одинаковыми. Это важно, т.к. в стек их помещает вызывающая функция, а удаляет - вызываемая. И если они не договорятся о размере, то программа скорее всего сломается (вслед за стеком)  smile 

Автор: jhonyxakep 3.3.2010, 08:01
Цитата(xvr @  2.3.2010,  17:56 Найти цитируемый пост)
то программа скорее всего сломается (вслед за стеком)   

жесть...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)