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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.64
KatyPet
4 / 4 / 0
Регистрация: 26.10.2012
Сообщений: 16
#1

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

26.10.2012, 00:33. Просмотров 1922. Ответов 29
Метки нет (Все метки)

Добрый вечер! Я первый раз пишу 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 и так далее.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.10.2012, 00:33
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как подключить пользовательскую DLL к приложению (C++):

Как подключить dll на C# к проекту (dll) на С++ - C++
Подскажите, пожалуйста, как подключить dll на C# к проекту (dll) на С++. В интернете много примеров, где показаны примеры по подключению...

Как подключить DLL - C++
Доброе время суток уважаемые участники Пытаюсь написать программу по работе с усб мостом, столкнулся с программной проблемой :)...

Как подключить dll к проекту? - C++
Ребят помогите пожалуйста, если сможете а то я уже 3 дня долбаюсь чет никак не могу разобраться с этими dll. вот я написал код dll-ки ...

как подключить dll и lib SDL - C++
как подключить к проекту(в Visual Studio 2010) библиотеку SDL?// есть SDL.dll, SDL.lib и SDLmain.lib и еще папка с include'ами

Как подключить библиотеку i7000.dll? - C++
у меня есть библиотека i7000.dll библиотека необходимая для работы с com портами все остальное работает нормально а эта работает только с 3...

Не удается подключить к приложению gtest и свою статическую либу VS 2010 - C++
Здравствуйте, господа. Возникла проблема с линкером в VS 2010 после подключения к консольному приложению собственной же статической...

29
Игорь с++
436 / 459 / 16
Регистрация: 26.01.2011
Сообщений: 2,032
27.10.2012, 20:19 #16
Вот смотри накидал простенькую dll которая просто выводит надпись в окне , и программу которая загружает эту dll делает все необходимые проверки и если всё нормально , то использует функцию из dll.
0
Вложения
Тип файла: rar Project1.rar (323.9 Кб, 15 просмотров)
KatyPet
4 / 4 / 0
Регистрация: 26.10.2012
Сообщений: 16
27.10.2012, 21:37  [ТС] #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.
0
Игорь с++
436 / 459 / 16
Регистрация: 26.01.2011
Сообщений: 2,032
27.10.2012, 21:49 #18
Цитата Сообщение от KatyPet Посмотреть сообщение
Почему-то появляется ошибка при компиляции
а портатип записала в dll.h и подключила к dllmain ?
1
Kastaneda
Нарушитель
Эксперт С++
4676 / 2880 / 234
Регистрация: 12.12.2009
Сообщений: 7,314
Записей в блоге: 2
Завершенные тесты: 1
27.10.2012, 21:57 #19
тыц
1
ValeryS
Модератор
6679 / 5088 / 475
Регистрация: 14.02.2011
Сообщений: 17,081
27.10.2012, 22:33 #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 более сложные методы программирования
по моему очень подробно и понятно написано
1
Kastaneda
Нарушитель
Эксперт С++
4676 / 2880 / 234
Регистрация: 12.12.2009
Сообщений: 7,314
Записей в блоге: 2
Завершенные тесты: 1
28.10.2012, 09:56 #21
Проблема в том, что функция называется MyClass::hw, а ТС пытается ее найти как hw. Я же дал ссылку на аналогичную проблему.
Советую выяснить как она реально называется в DLL. Помнится под виндой это можно посмотреть в Total Commander, там на DLL'ке нажать "просмотр" и будет показана вся инфа о DLL, в т.ч. реальное имя функции. Вот по этому имени ее и надо искать.
1
KatyPet
4 / 4 / 0
Регистрация: 26.10.2012
Сообщений: 16
30.10.2012, 23:03  [ТС] #22
а портатип записала в dll.h и подключила к dllmain ?
Подключила.

Добавлено через 1 час 17 минут
Спасибо всем. Наконец-то программа работает! Оказывается, надо было писать так:
C++
1
hw=GetProcAddress(hLib, "?hw@@YAXXZ")
Оказывается, так называлась эта функция в скомпилированной DLL. А скажите, по какому принципу формируется это название?
0
Игорь с++
436 / 459 / 16
Регистрация: 26.01.2011
Сообщений: 2,032
30.10.2012, 23:26 #23
Цитата Сообщение от KatyPet Посмотреть сообщение
Оказывается, так называлась эта функция в скомпилированной DLL. А скажите, по какому принципу формируется это название?
то , что вы нашли название функции с помощью какой то программы это не выход из ситуации.
1)Вы что то не верно сделали при написании dll
2)название формируется по принцепу - х...р поймёш и пока , что тебе на это замориваться не надо , лучше сделай нормальную dll с нормальным видимым названием , ты хотя бы открой мою dll , увидеш такой ужас как у тебя ?
1
ValeryS
Модератор
6679 / 5088 / 475
Регистрация: 14.02.2011
Сообщений: 17,081
30.10.2012, 23:53 #24
Цитата Сообщение от KatyPet Посмотреть сообщение
"?hw@@YAXXZ"
Цитата Сообщение от KatyPet Посмотреть сообщение
А скажите, по какому принципу формируется это название?
тут заложено имя функции и её параметры
т.е зашифровано это void hw(void)
в отличии от C соглашения где просто бы передалось имя hw, а потом гадай что принимает функция и сколько, без h файла или исходников, только декомпилировать dll

Добавлено через 25 минут
кстати функцию можно грузить не по имени а по ординалу
1
KatyPet
4 / 4 / 0
Регистрация: 26.10.2012
Сообщений: 16
31.10.2012, 20:30  [ТС] #25
Написала в My.h так:
C++
1
2
3
4
5
6
7
8
#ifdef __cplusplus
extern "C"
{
#endif
__declspec(dllexport) void hw(void);
#ifdef __cplusplus
}
#endif
Работает, теперь имя функции в DLL не искажается.
0
Игорь с++
436 / 459 / 16
Регистрация: 26.01.2011
Сообщений: 2,032
31.10.2012, 22:37 #26
Цитата Сообщение от KatyPet Посмотреть сообщение
Работает, теперь имя функции в DLL не искажается.
Вот это другое дело !!! Молодец !!! Хотя я тебе давал пример dll уже давно , но как говорят на ошибках учится .
0
KatyPet
4 / 4 / 0
Регистрация: 26.10.2012
Сообщений: 16
31.10.2012, 22:53  [ТС] #27
Теперь хочу написать программу, которая будет использовать не мою DLL, а kernel32.dll.
Вот что написала:
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
#include "stdafx.h"
#include<iostream>
#include<conio.h>
#include<windows.h>
void ( __cdecl *MyBeep)(int freq, int dur);
HMODULE hLib;
int main()
{
    if(!(hLib=LoadLibrary(_T("kernel32.dll"))))
    {
        std::cout<<"LoadLibrary doesn't work\n";
        getch();
        return 0;
    }
    if(!((FARPROC &)MyBeep=GetProcAddress(hLib, "Beep")))
    {
        std::cout<<"GetProcAddress doesn't work\n";
        getch();
        return 0;
    }
    MyBeep(10000,1000);
    std::cout<<"kernel32 used\n";
    getch();
    return 0;
}
Оно работает, бибип звучит, но после этого вылезает такая ошибка: "The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convertation with a function pointer declared with a different calling convertation.".
Перевела в яндексе: "
Значение ESP не была должным образом сохраненные на вызов функции. Это, как правило, результат вызова функции, объявленные с одного вызова convertation с указатель функции, объявленные с другой вызов convertation."
И все равно не поняла, в чем проблема
0
Игорь с++
436 / 459 / 16
Регистрация: 26.01.2011
Сообщений: 2,032
31.10.2012, 23:36 #28
а вот так -
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 <cstdlib>
#include <iostream>
#include <windows.h>
 
using namespace std;
 
int main(int argc, char *argv[])
{
    
    typedef void  (__stdcall *Beep)(int a,int b);
    HINSTANCE kernel;
    Beep  My(NULL);
    
    kernel = LoadLibrary("C:/WINDOWS/system32/kernel32.dll");
 
if(kernel==0){return 0;}
 
My = (Beep) GetProcAddress ( kernel , "Beep" );
 
if(My==0){return 0;}
 
My(500,500);
    
    system("PAUSE");
    return EXIT_SUCCESS;
}
1
KatyPet
4 / 4 / 0
Регистрация: 26.10.2012
Сообщений: 16
01.11.2012, 01:17  [ТС] #29
Спасибо!
0
ValeryS
Модератор
6679 / 5088 / 475
Регистрация: 14.02.2011
Сообщений: 17,081
01.11.2012, 08:44 #30
Цитата Сообщение от KatyPet Посмотреть сообщение
после этого вылезает такая ошибка: "The value of ESP was not properly saved across a function call.
я же тебе писал обрати внимание
Цитата Сообщение от ValeryS Посмотреть сообщение
соглашение по вызову __cdec есть еще __stdcall (на самом деле их больше это самые главные)от этого зависит кто чистит стек и как передаются параметры (прочитай про них обязательно неправильное условие роняет программу)
http://msdn.microsoft.com/ru-ru/library/zkwh89ks.aspx
http://msdn.microsoft.com/ru-ru/library/zxk0tw93.aspx
1
01.11.2012, 08:44
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.11.2012, 08:44
Привет! Вот еще темы с ответами:

Приложению не удалось запуститься, поскольку MSVCR90D.dll не был найден - C++
Приложению не удалось запуститься, поскольку MSVCR90D.dll не был найден. Иногда при отладке возникает данная ошибка. В чем проблема и...

Как создать файл DLL так, чтобы его можно было подключить к VBA Excel? - C++
Пытаясь научиться подключать к VBA хотя бы самую тривиальную функцию на C++. Для примера написал на C++ простую функцию Kvadrat и...

Подключить dll - C++
Здравствуйте. Есть dll, в ней несколько функций, необходимо добавить еще одну, чтобы выводила окно с приветствием. И затем написать win...

Подключить dll к программе - C++
Здравствуйте. Нужна помощь новичку. У меня есть файл, к примеру biblioteka.dll. Каким оброазом можно подключить эту библиотеку к моей...


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

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru