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

Ссылка на экземпляр класса в DLL - C++

Восстановить пароль Регистрация
 
maxon887
 Аватар для maxon887
12 / 12 / 3
Регистрация: 05.06.2012
Сообщений: 280
25.10.2013, 23:08     Ссылка на экземпляр класса в DLL #1
Написал маленький каркасик для собственново фреймворка, и проблема возникла когда хотель экспортировать его в DLL. Фреймворк предпологает запуск приложения следующим образом:
C++
1
2
3
4
5
6
7
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE prevInstance,LPSTR cmdLine,int cmdShow)
{
    apl = new Application(hInstance);
    Window w(NULL,L"Wirst Class",L"Example2",WS_OVERLAPPEDWINDOW|WS_VISIBLE,
             0,0,400,400,NULL,NULL);
    return apl->Run();
}
указатель apl описан в файле globals.h как
C++
1
2
class Application;
extern Application* apl;
и имеет реально обьявление в другом файле.
Классы которые должны экспортироваться в либу я пометил как __declspec(dllexport)
А вот что делать с Application* apl незнаю.
при попытки скомпилить пишет:
main.obj:-1: ошибка: LNK2001: unresolved external symbol "class Application * apl" (?apl@@3PAVApplication@@A)
ну и это логично)

Добавлено через 6 часов 34 минуты
Ну что никто не знает как решить проблему? может исходники скинуть?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Avazart
 Аватар для Avazart
6893 / 5133 / 250
Регистрация: 10.12.2010
Сообщений: 22,560
Записей в блоге: 17
25.10.2013, 23:11     Ссылка на экземпляр класса в DLL #2
Цитата Сообщение от maxon887 Посмотреть сообщение
может исходники скинуть?
Вероятно стоит..

А вообще классы в dll это как по мне не очень идея.
maxon887
 Аватар для maxon887
12 / 12 / 3
Регистрация: 05.06.2012
Сообщений: 280
25.10.2013, 23:24  [ТС]     Ссылка на экземпляр класса в DLL #3
Правда тут ещё WinAPI много, так я незнал куда тему создавать.
Класс Application служит для загрузки основного цикла приложения и для получения сообшений от винды.
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//application.h
#ifndef APPLICATION_H
#define APPLICATION_H
#include <Windows.h>
#include "window.h"
class __declspec(dllexport) Application
{
public:
    Application(HINSTANCE hInstance);
    LRESULT Run();
    HINSTANCE GetInstance();
protected:
    HINSTANCE hInstance;
};
 
#endif // APPLICATION_H
 
//application.cpp
#include "application.h"
__declspec(dllexport) Application* apl = NULL;
Application::Application(HINSTANCE hInstance)
{
    this->hInstance = hInstance;
}
 
LRESULT Application::Run()
{
    MSG msg;
    while(GetMessage(&msg,NULL,0,0))
    {
        if(msg.hwnd==NULL)
            continue;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
 
HINSTANCE Application::GetInstance()
{
    return hInstance;
}
Класс Window служит для создания объекта окна, и далешь будет развиваться в сторону абстракного класса
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//window.h
#ifndef WINDOW_H
#define WINDOW_H
#include "application.h"
#include "globals.h"
class __declspec(dllexport) Window
{
public:
    Window(DWORD dwExStyle,LPCTSTR lpszClassName,LPCTSTR lpszWindowName,DWORD dwStyle,
            int x,int y,int nWidth,int nHeight,HWND hwndParent,HMENU nIDorHMenu);
    static Window* FindWindow(HWND hWnd);
    static LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
    ~Window();
protected:
    HWND hWnd;
};
 
#endif // WINDOW_H
 
//window.cpp
#include "window.h"
#include <vector>
using namespace std;
vector<Window*> LIST;
Window::Window(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName,
               DWORD dwStyle, int x, int y, int nWidth, int nHeight,
               HWND hwndParent, HMENU nIDorHMenu)
{
    LIST.push_back(this);
    hWnd = NULL;
    WNDCLASSEX win;
    win.cbSize = sizeof(WNDCLASSEX);
    win.style = CS_VREDRAW|CS_HREDRAW|CS_OWNDC|CS_DBLCLKS;
    win.lpfnWndProc = Window::WinProc;
    win.cbClsExtra = 0;
    win.cbWndExtra = 0;
    win.hInstance = apl->GetInstance();
    win.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    win.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
    win.hCursor = LoadCursor(NULL,IDC_ARROW);
    win.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    win.lpszMenuName = NULL;
    win.lpszClassName = lpszClassName;
    RegisterClassEx(&win);
    hWnd = CreateWindowEx(NULL,lpszClassName,lpszWindowName,
                          WS_OVERLAPPEDWINDOW|WS_VISIBLE,
                          x,y,nWidth,nHeight,NULL,NULL,apl->GetInstance(),NULL);
 
}
 
Window *Window::FindWindowW(HWND hWnd)
{
    if(hWnd)
    {
        Window* current;
        for(int i = 0; i<LIST.size();i++)
        {
           current = LIST[i];
           if(current->hWnd == hWnd)
               return current;
        }
    }
    return NULL;
}
 
LPARAM Window::WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
    case WM_CREATE:
    {
        break;
    }
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd,&ps);
        //перерисовка окна
        EndPaint(hWnd,&ps);
        break;
    }
    case WM_DESTROY:
    {
        Window* current = FindWindow(hWnd);
        for(int i = 0; i<LIST.size();i++)
        {
            if(LIST[i] == current)
            {
                LIST.erase(LIST.begin()+i);
            }
        }
        if(LIST.size() == 0)
            PostQuitMessage(0);
        return 0;
    }
    default:
        break;
    }
    return(DefWindowProc(hWnd,msg,wParam,lParam));
}
 
Window::~Window()
{
}
//global.h - обьявление глобальных переменных
C++
1
2
3
4
5
6
7
8
9
10
#ifndef GLOBALS_H
#define GLOBALS_H
#include <Windows.h>
#include <vector>
using namespace std;
class Application;
class Window;
extern Application* apl;
extern vector<Window*> LIST;
#endif // GLOBALS_H
Добавлено через 4 минуты
Цитата Сообщение от Avazart Посмотреть сообщение
Вероятно стоит..

А вообще классы в dll это как по мне не очень идея.
Просветите меня пожалуйста
Avazart
 Аватар для Avazart
6893 / 5133 / 250
Регистрация: 10.12.2010
Сообщений: 22,560
Записей в блоге: 17
25.10.2013, 23:27     Ссылка на экземпляр класса в DLL #4
Цитата Сообщение от maxon887 Посмотреть сообщение
Просветите меня пожалуйста
Ну как бы сможешь использовать dll только под VC++, а под другими комипиляторами нет.

Поэтому смысл? Почему сразу не распространять либу исходниками ?
ValeryS
Модератор
6373 / 4839 / 440
Регистрация: 14.02.2011
Сообщений: 16,038
25.10.2013, 23:29     Ссылка на экземпляр класса в DLL #5
Цитата Сообщение от maxon887 Посмотреть сообщение
Просветите меня пожалуйста
пожалуйста
классы используются в плюсах, а там есть искажение имен
выдергивать из библиотеки не удобно
если использовать Си стиль то классов не будет
Avazart
 Аватар для Avazart
6893 / 5133 / 250
Регистрация: 10.12.2010
Сообщений: 22,560
Записей в блоге: 17
25.10.2013, 23:32     Ссылка на экземпляр класса в DLL #6
C++
1
2
Window w( NULL,L"Wirst Class",L"Example2",
                       WS_OVERLAPPEDWINDOW|WS_VISIBLE, 0,0,400,400,NULL,NULL);

Не по теме:

Вас такая запись не пугает ?
Нет, тогда зачем вообще было "обворачивать" ?

Ну а вообще идея создать свой фреймворк очень интересна на мой взгляд.

ValeryS
Модератор
6373 / 4839 / 440
Регистрация: 14.02.2011
Сообщений: 16,038
25.10.2013, 23:38     Ссылка на экземпляр класса в DLL #7
если хочешь использовать классы в дллке необходим интерфейс
вот тут так поверхностно рассматривается этот вопрос
http://www.xserver.ru/computer/langprogr/c_c2p/12/
maxon887
 Аватар для maxon887
12 / 12 / 3
Регистрация: 05.06.2012
Сообщений: 280
26.10.2013, 00:42  [ТС]     Ссылка на экземпляр класса в DLL #8
ну ладно, проблемма с классами не самая актуальная, первая проблема в том что Application* apl; не видно из вне библиотеки.
Avazart
 Аватар для Avazart
6893 / 5133 / 250
Регистрация: 10.12.2010
Сообщений: 22,560
Записей в блоге: 17
26.10.2013, 00:52     Ссылка на экземпляр класса в DLL #9
C++
1
__declspec(dllexport) Application* apl = NULL;
А что это вообще ? Зачем "оно" в хедере?

Цитата Сообщение от maxon887 Посмотреть сообщение
C++
1
apl = new Application(hInstance);
Почему не по нормальному :
C++
1
Application app(hInstance);

Не по теме:

Application по логике должен реализовывать паттерн синглетон.

maxon887
 Аватар для maxon887
12 / 12 / 3
Регистрация: 05.06.2012
Сообщений: 280
26.10.2013, 01:08  [ТС]     Ссылка на экземпляр класса в DLL #10
Цитата Сообщение от Avazart Посмотреть сообщение
А что это вообще ? Зачем "оно" в хедере?
это инициализация ссылки на на обект "приложение". Оно не в хедере а в исходнике. В хедере только
C++
1
extern Application* apl;
оно не по нормальному, потому что остальная часть кода ссылаеться на методы экземпляра класса приложения. Кторый существует как токавой только уже в ран-тайме

Добавлено через 1 минуту
за __delcspec(dllexport) извиняю, эксперементировал. Изначально было просто
C++
1
Application* apl = NULL;
Avazart
 Аватар для Avazart
6893 / 5133 / 250
Регистрация: 10.12.2010
Сообщений: 22,560
Записей в блоге: 17
26.10.2013, 01:19     Ссылка на экземпляр класса в DLL #11
Почему не сделать к подобно тому как сделано в VCL :
C++
1
Application->CreateForm( ... );
Подобным образом "окно" будет создаваться и сразу передаваться "приложению"
Или передавать в конструктор "окна" объект приложения.

C++
1
2
Application app;
Window w(app);
Добавлено через 7 минут
Цитата Сообщение от maxon887 Посмотреть сообщение
оно не по нормальному, потому что остальная часть кода ссылаеться на методы экземпляра класса приложения. Кторый существует как токавой только уже в ран-тайме
Ну я и говорю не по нормальному...
Разве "окно" должно знать о "приложении" ?
maxon887
 Аватар для maxon887
12 / 12 / 3
Регистрация: 05.06.2012
Сообщений: 280
26.10.2013, 01:44  [ТС]     Ссылка на экземпляр класса в DLL #12
Avazart, два представленных варианта не рассматриваються потому, что на уровне интерфейсов приложение и окна не должны ничего знать друг, о друге. Я думаю понятно почему.
Кстати как то странно ведут себя ссылки в либе, допустим следующи код падает во время выполнения
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
27
28
29
30
31
//dynamiclib.h
#ifndef DYNAMICLIB_H
#define DYNAMICLIB_H
 
__declspec(dllexport) int exportValue;
__declspec(dllexport) int* link;
#include <iostream>
using namespace std;
 
class __declspec(dllexport) DynamicLib {
public:
    DynamicLib();
    static void Hello();
};
 
#endif // DYNAMICLIB_H
 
//dynamiclib.cpp
#include "dynamiclib.h"
 
 
DynamicLib::DynamicLib()
{
    exportValue = 10;
    link = &exportValue;
}
 
void DynamicLib::Hello()
{
    cout<<"Hello from DLL "<<*link<<endl;
}
Вызов из вне
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
using namespace std;
#include "dynamiclib.h"
int main()
{
    cout << "Hello World!" << endl;
    DynamicLib::Hello();
    return 0;
}
Добавлено через 8 минут
Оо нащёл на msdn
You cannot initialize a static data pointer with the address of a data object declared with the dllimport attribute.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.10.2013, 18:18     Ссылка на экземпляр класса в DLL
Еще ссылки по теме:

Как сделать членом класса экземпляр этого же класса C++
Функция, возвращающая экземпляр класса C++
C++ Классы и объекты в С++, компонента класса и экземпляр класса

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

Или воспользуйтесь поиском по форуму:
maxon887
 Аватар для maxon887
12 / 12 / 3
Регистрация: 05.06.2012
Сообщений: 280
27.10.2013, 18:18  [ТС]     Ссылка на экземпляр класса в DLL #13
Проблемо была в том что, глобальные переменные либы нельзя менять влоб, тоесть если переменная
C++
1
__declspec(dllexport) extern int i;
то из испольняемого модуля можно только её считать(по крайней мере я незнаю как изменять её не из функций)
сделал следующие в конструкторе Application.
C++
1
2
    delete apl;
    apl = this;
теперь всё работе + ещё круче стало))) теперь это как бы синглетон))

Добавлено через 2 минуты
напоминаю что рание запус фреймворка подразумевал
C++
1
apl = new Application(HINSTANCE);
теперь
C++
1
Application *apl = new Application(HINSTANCE);
Yandex
Объявления
27.10.2013, 18:18     Ссылка на экземпляр класса в DLL
Ответ Создать тему
Опции темы

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