Форум программистов, компьютерный форум CyberForum.ru

Как подключить пользовательскую DLL к приложению - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.64
KatyPet
4 / 4 / 0
Регистрация: 26.10.2012
Сообщений: 16
26.10.2012, 00:33     Как подключить пользовательскую DLL к приложению #1
Добрый вечер! Я первый раз пишу dll. Вот ее текст:
My.cpp:
C++
1
2
3
4
5
6
7
#include<iostream>
#include "My.h"
using namespace std;
namespace myspace
{
    void MyClass::hw(void) {cout<<"HelloWorld";}
}
И My.h:
C++
1
2
3
4
5
6
7
8
namespace myspace
{
    class MyClass
    {
    public:
        static __declspec(dllexport) void hw(void);
    };
}
Компилирую в Visual Studio, всё нормально.
А теперь пытаюсь написать программу, которая будет использовать эту dll. Вот здесь проблема. Вот текст этой программы:
UsesDll.cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include "stdafx.h"
#include "My.h"
#include<iostream>
#include<conio.h>
#pragma comment(lib, "?.lib")
int main()
{
    myspace::MyClass::hw();
    std::cout<<"Dll used\n";
    getch();
    return 0;
}
My.h:
C++
1
2
3
4
5
6
7
8
namespace myspace
{
    class MyClass
    {
    public:
        static __declspec(dllexport) void hw(void);
    };
}
И там еще stafx.h, stdafx.cpp и targetver.h, которые Visual Studio добавило само.
Так вот, эта программа не линкуется - появляется ошибка:
error LNK2019: unresolved external symbol "public: static void __cdecl myspace::MyClass::hw(void)" (?hw@MyClass@myspace@@SAXZZ) referenced in function _main.
Что посоветуете?

Добавлено через 19 минут
Точнее, в пятой строке файла UsesDll.cpp нет никакого pragma и так далее.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.10.2012, 00:33     Как подключить пользовательскую DLL к приложению
Посмотрите здесь:

C++ как подключить dll к проекту с++
Подключить библ. bass.dll C++
C++ Подключить dll к программе
как подключить dll и lib SDL C++
Подключить dll C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
26.10.2012, 09:11     Как подключить пользовательскую DLL к приложению #2
Посмотри, может поможет.
KatyPet
4 / 4 / 0
Регистрация: 26.10.2012
Сообщений: 16
26.10.2012, 11:04  [ТС]     Как подключить пользовательскую DLL к приложению #3
Посмотрела тему по ссылке. Теперь код моей программы, использующей DLL, выглядит так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef void (*hw)(void);
#include "stdafx.h"
#include "My.h"
#include<iostream>
#include<conio.h>
int main()
{
    HMODULE hLib=LoadLibrary(LPCWSTR("MyDll.dll"));
    hw func=(hw)GetProcAddress(hLib, "hw");
    func();
    std::cout<<"Dll used\n";
    getch();
    return 0;
}
Теперь программа компилируется и линкуется нормально, но не работает. Она останавливается на месте вызова func() и говорит "Unhandled exception at 0x00000000 in UsesDll.exe: 0xC0000005: Access violation".
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
26.10.2012, 11:08     Как подключить пользовательскую DLL к приложению #4
Код DLL тоже поменяй.

Добавлено через 1 минуту
C++
1
2
3
4
5
BOOL _stdcall DllMain(HINSTANCE hInst, DWORD Reason, LPVOID reserved){
  if(Reason==DLL_PROCESS_ATTACH)
       hInstance = hInst;
       return true;
}
DllMain обязательная функция.
KatyPet
4 / 4 / 0
Регистрация: 26.10.2012
Сообщений: 16
26.10.2012, 17:54  [ТС]     Как подключить пользовательскую DLL к приложению #5
Поменяла код dll. Теперь он такой: MyDll.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
#include "My.h"
#include<windows.h>
using namespace std;
HINSTANCE hInstance=NULL;
namespace myspace
{
    BOOL _stdcall DllMain(HINSTANCE hInst, DWORD Reason, LPVOID reserved)
    {
       if(Reason==DLL_PROCESS_ATTACH)
       {
          hInstance = hInst;
          return true;
        }
    }
    void MyClass::hw(void) {cout<<"HelloWorld";}
}
А все равно при запуске та же ошибка.
Я думаю, проблема не в DLL, а в программе, использующей DLL. Потому что я попробовала ее запустить, не подкладывая DLL рядом с ней в папку, и, вместо того, чтоб вывести сообщение, что требуется такая-то DLL (как это делают нормальные программы), она выдает все ту же ошибку.
Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
26.10.2012, 22:26     Как подключить пользовательскую DLL к приложению #6
есть два метода загрузки dll статитческий и динамический если загружать статически и не класть dll рядом то будет то сообщение о котором ты писала , а вот если динамически и не положить dll , то бог знает , что может произойти , может и вообще не чего , а может и программа провалиться с грохотом, ты уж определись как ты хочеш её загрузить !
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11840 / 6819 / 771
Регистрация: 27.09.2012
Сообщений: 16,911
Записей в блоге: 2
Завершенные тесты: 1
26.10.2012, 22:30     Как подключить пользовательскую DLL к приложению #7
Цитата Сообщение от Игорь с++ Посмотреть сообщение
есть два метода загрузки dll статитческий и динамический если загружать статически и не класть dll рядом то будет то сообщение о котором ты писала , а вот если динамически и не положить dll , то бог знает , что может произойти , может и вообще не чего , а может и программа провалиться с грохотом, ты уж определись как ты хочеш её загрузить !
Само название DLL дает понять, что это должна быть динамическая библиотека
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,051
26.10.2012, 22:35     Как подключить пользовательскую DLL к приложению #8
Цитата Сообщение от Игорь с++ Посмотреть сообщение
динамический
это LoadLibrary и тогда нужно не класть рядом а прописать путь к dl
если путь не прописать то будет искать в своей папке папке видос и как там пути настроены
и конечно проверять что возвращает функция
C++
1
2
if(!(dasWordl_dll=LoadLibrary("имя библиотеки")))
        return false;// ошибка загрузки делать нечего
Цитата Сообщение от Игорь с++ Посмотреть сообщение
статически и не класть dll рядом
а вот это на этапе компиляции и нужна не Dll а lib, которая так же компилируется при создании Dll
но если в настройках компилятора стоит линковать динамически то Dll тоже нужна и рядом с программой или в системных папках
Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
26.10.2012, 22:58     Как подключить пользовательскую DLL к приложению #9
Цитата Сообщение от Croessmah Посмотреть сообщение
Само название DLL дает понять, что это должна быть динамическая библиотека
название может и даёт понятие , но способа загрузки два !

Цитата Сообщение от ValeryS Посмотреть сообщение
это LoadLibrary и тогда нужно не класть рядом а прописать путь к dl
если путь не прописать то будет искать в своей папке папке видос и как там пути настроены
во первых согласен , что не обязательно , но с другой стороны если не прописать путь и не положить либо рядом либо в системную папку ОС , то интересно посмотреть , что из этого у тебя получится ?
Цитата Сообщение от ValeryS Посмотреть сообщение
а вот это на этапе компиляции и нужна не Dll а lib, которая так же компилируется при создании Dll
я про это и говорил , но нужна она только на этапе компиляции , да и ещё даже если ты и линкуеш статически , то даже и в этом случае не обязательно держать dll в своей папке , её так же можно бросить в системную папку ОС.
ValeryS
26.10.2012, 22:59
  #10

Не по теме:

Цитата Сообщение от Игорь с++ Посмотреть сообщение
то интересно посмотреть , что из этого у тебя получится ?
а ничего не получится
правда узнаешь ты об этом на этапе исполнения, компилятор слова не скажет
для этого и нужна проверка

Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
26.10.2012, 23:01     Как подключить пользовательскую DLL к приложению #11
Цитата Сообщение от ValeryS Посмотреть сообщение
а ничего не получится
для этого и нужна проверка
согласен , но может и прога провалиться
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,051
26.10.2012, 23:04     Как подключить пользовательскую DLL к приложению #12
Цитата Сообщение от Игорь с++ Посмотреть сообщение
то даже и в этом случае не обязательно держать dll в своей папке , её так же можно бросить в системную папку ОС.
ну а я про что
Цитата Сообщение от ValeryS Посмотреть сообщение
то Dll тоже нужна и рядом с программой или в системных папках
пардон опечатка
читать так
Цитата Сообщение от ValeryS Посмотреть сообщение
то Dll тоже нужна или рядом с программой или в системных папках
Добавлено через 2 минуты
Цитата Сообщение от Игорь с++ Посмотреть сообщение
согласен , но может и прога провалиться
перечитай сообщение я добавил
Цитата Сообщение от ValeryS Посмотреть сообщение
правда узнаешь ты об этом на этапе исполнения, компилятор слова не скажет
а для того чтобы не валилась после проверки или экстренный выход или пиши сообщение пользователю "не могу найти"
Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
26.10.2012, 23:05     Как подключить пользовательскую DLL к приложению #13
мы с тобой пробуем объснить друг другу , что и так сами понимаем , а вот ТС когда почитает всё это наверно будет в таком состаянии -
KatyPet
4 / 4 / 0
Регистрация: 26.10.2012
Сообщений: 16
27.10.2012, 14:06  [ТС]     Как подключить пользовательскую DLL к приложению #14
Из всего, что вы написали, я поняла, что хочу сделать динамический метод загрузки. Использую LoadLibrary в коде программы. Не прописываю путь к DLL, но кладу ее в папку рядом с программой. И все равно, при текстах программы и DLL, которые я выложила ранее, программа ломается в момент вызова func. В чем проблема?
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,051
27.10.2012, 14:24     Как подключить пользовательскую DLL к приложению #15
Я тебе приведу кусок моей проги как работать с dll
C++
1
2
3
4
5
6
7
8
9
10
// объявить глобально чтобы все видели
int( __cdecl*DasWordInit)(char); //указатель на функцию описывается её прототип и соглашение по вызову
 HMODULE dasWordl_dll; // хандлер библиотеки
int init_DasWord()
{
 
    if(!(dasWordl_dll=LoadLibrary(_T("Dasword.dll")))) // загружаем библиотеку
        return 0; // если не загрузилась делать нечего выходим,можно чтото написать пользователю
  if(!((FARPROC &)DasWordInit=GetProcAddress(dasWordl_dll, "DasWordInit")))// загружаем функцию
        return 0;// если не загрузилась делать нечего выходим
и только потом можно вызвать функцию
C++
1
DasWordInit(0);
соглашение по вызову __cdec есть еще __stdcall (на самом деле их больше это самые главные)от этого зависит кто чистит стек и как передаются параметры (прочитай про них обязательно неправильное условие роняет программу)
http://msdn.microsoft.com/ru-ru/library/zkwh89ks.aspx
http://msdn.microsoft.com/ru-ru/library/zxk0tw93.aspx
Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
27.10.2012, 20:19     Как подключить пользовательскую DLL к приложению #16
Вот смотри накидал простенькую dll которая просто выводит надпись в окне , и программу которая загружает эту dll делает все необходимые проверки и если всё нормально , то использует функцию из dll.
Вложения
Тип файла: rar Project1.rar (323.9 Кб, 13 просмотров)
KatyPet
4 / 4 / 0
Регистрация: 26.10.2012
Сообщений: 16
27.10.2012, 21:37  [ТС]     Как подключить пользовательскую DLL к приложению #17
Попробовала применить совет ValeryS. Теперь DLL выглядит так:
My.h:
C++
1
2
3
4
5
class MyClass
{
public:
    static __declspec(dllexport) void hw(void);
};
MyDll.cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<iostream>
#include "My.h"
#include<windows.h>
using namespace std;
HINSTANCE hInstance=NULL;
void MyClass::hw(void) {cout<<"HelloWorld";}
bool _stdcall DllMain(HINSTANCE hInst, DWORD Reason, LPVOID reserved)
{
    if(Reason==DLL_PROCESS_ATTACH)
    {
        hInstance=hInst;
        return true;
    }
}
,
Программа, использующая DLL:
My.h такое же, а UsesDll.cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "stdafx.h"
#include "My.h"
#include<iostream>
#include<conio.h>
#include<windows.h>
void ( __cdecl *hw)(void);
HMODULE hLib;
int main()
{
    if(!(hLib=LoadLibrary(_T("MyDll.dll"))))
    {
        std::cout<<"LoadLibrary doesn't work\n";
        getch();
        return 0;
    }
    if(!((FARPROC &)hw=GetProcAddress(hLib, "hw")))
    {
        std::cout<<"GetProcAddress doesn't work\n";
        getch();
        return 0;
    }
    hw();
    std::cout<<"Dll used\n";
    getch();
    return 0;
}
LoadLibrary уже работает.
Выдает, что не работает GetProcAddress.


Попробовала скомпилировать проект, который прислал Игорь. Почему-то появляется ошибка при компиляции error C2491: 'MyFunc' : definition of dllimport function not allowed, это в dllmain.cpp.
Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
27.10.2012, 21:49     Как подключить пользовательскую DLL к приложению #18
Цитата Сообщение от KatyPet Посмотреть сообщение
Почему-то появляется ошибка при компиляции
а портатип записала в dll.h и подключила к dllmain ?
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
27.10.2012, 21:57     Как подключить пользовательскую DLL к приложению #19
тыц
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.10.2012, 22:33     Как подключить пользовательскую DLL к приложению
Еще ссылки по теме:

C++ Не удается подключить к приложению gtest и свою статическую либу VS 2010
Как подключить DLL C++
C++ Как подключить dll на C# к проекту (dll) на С++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,051
27.10.2012, 22:33     Как подключить пользовательскую DLL к приложению #20
Цитата Сообщение от KatyPet Посмотреть сообщение
Выдает, что не работает GetProcAddress.
открой свою длл в редакторе например PE Explorer и посмотри как выглядит твоя функция
сдается мне что ты не сделала условие "в стиле С" при написании Dll (по крайней мере я не заметил) и название твоей функции исказилось по плюсовым правилам
и она уже называется не hw а по другому

Добавлено через 6 минут
Вот это условие у Игорь с++,
C++
1
2
3
4
#ifdef __cplusplus
extern "C"
{
#endif
добавь это условие в My.h:
хотя твоя функция это метод класса и честно говоря я не знаю куда впихнуть extern "C"
попробуй сначала написать простую функцию типа
C++
1
extern "C" __declspec(dllexport) void hw(void);
и побаловаться с ней

Добавлено через 9 минут
а вообще порекомендую тебе книгу
Дж Рихтер К Назар "Windows via C/C++ программирование на языке Visual C++" Питер 2009
глава 19 Dll основы
глава 20 Dll более сложные методы программирования
по моему очень подробно и понятно написано
Yandex
Объявления
27.10.2012, 22:33     Как подключить пользовательскую DLL к приложению
Ответ Создать тему
Опции темы

Текущее время: 21:05. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru