Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Экспорт класса из DLL и использование глобальных п 
:(
    Опции темы
erslgoeirjh
Дата 26.1.2015, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 16.12.2005

Репутация: нет
Всего: нет



Я создал в Visual Studio 2008 DLL (консольное приложение, которое я пометил галочкой при создании как DLL), которая экспортирует класс, и создал приложение, которое загружает эту DLL и импортирует оттуда этот класс:

1) библиотека MyFirstDll.dll:

файл stdafx.h :
 
Код

// stdafx.h: включаемый файл для стандартных системных включаемых файлов
// или включаемых файлов для конкретного проекта, которые часто используются, но
// не часто изменяются
//
 
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN             // Исключите редко используемые компоненты из заголовков Windows
// Файлы заголовков Windows:
#include <windows.h>
#include <stdio.h>
 
 
// TODO. Установите здесь ссылки на дополнительные заголовки, требующиеся для программы
#include "MyFirstDll.h"


файл MyFirstDll.h :

Код

#ifndef MYFIRSTDLL_H
#define MYFIRSTDLL_H
#include <windows.h>
 
class IMyClass
{
public:
    virtual void __stdcall Demo(char *str)=0;
    virtual ~IMyClass(){}
};
 
typedef IMyClass* (__cdecl *create_t)();
 
class MyClass: public IMyClass
{
public:
    MyClass(){}
    virtual void __stdcall Demo(char *str) { printf("%s",str); }
    virtual ~MyClass(){}
};
#endif


файл dllmain.cpp :

Код

// dllmain.cpp: определяет точку входа для приложения DLL.
#include "stdafx.h"
 
extern "C" __declspec(dllexport)  IMyClass* __cdecl create()
{
    return new MyClass();
}
 
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}


2) вызывающая программа CallMyFirstDll :

файл stdafx.h :
 
Код

// stdafx.h: включаемый файл для стандартных системных включаемых файлов
// или включаемых файлов для конкретного проекта, которые часто используются, но
// не часто изменяются
//
 
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <conio.h>
#include <locale.h>
// TODO. Установите здесь ссылки на дополнительные заголовки, требующиеся для программы
#include "MyFirstDll.h"


файл MyFirstDll.h :

Код

#ifndef MYFIRSTDLL_H
#define MYFIRSTDLL_H
#include <windows.h>
 
class IMyClass
{
public:
    virtual void __stdcall Demo(char *str)=0;
    virtual ~IMyClass(){}
};
 
typedef IMyClass* (__cdecl *create_t)();
 
class MyClass: public IMyClass
{
public:
    MyClass(){}
    virtual void __stdcall Demo(char *str) { printf("%s",str); }
    virtual ~MyClass(){}
};
#endif


файл CallMyFirstDll.cpp :

Код

// CallMyFirstDll.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
 
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_CTYPE,"Russian");
    HINSTANCE  h=LoadLibrary(L"MyFirstDll.dll");
    if (!h)
    {
        printf("Ошибка загрузки MyFirstDll.dll !\n");
        printf("Нажмите любую клавишу для выхода из программы.\n");
        setlocale(LC_ALL,"English_UnitedStates.1252");
        getch();
        return -1;
    }
    printf("Загрузка MyFirstDll.dll прошла успешно!\n");
    create_t  create = (create_t)GetProcAddress(h,"create");
    if (!create)
    {
        printf("Ошибка вызова функции create у класса MyClass! \n");
        printf("Нажмите любую клавишу для выхода из программы.\n");
        setlocale(LC_ALL,"English_UnitedStates.1252");
        getch();
        return -1;
    }
    IMyClass* imyclass = create();
    imyclass->Demo("Test\n");
    printf("Вызов MyFirstDll.dll прошёл успешно!\n");
    delete imyclass;
    FreeLibrary(h);
    printf("Работа с MyFirstDll.dll завершена.\n");
    printf("Нажмите любую клавишу для выхода из программы.\n");
    setlocale(LC_ALL,"English_UnitedStates.1252");
    getch();
    return 0;
}


В связи с этим у меня есть два вопроса:
Откуда я взял работающий код и немного его переделал. Вот что у меня получилось:

1) Нужно ли в моём классе MyClass объявлять его данные и методы как static, или можно обойтись без этого?
2) Я хочу в функциях моей DLL использовать глобальные переменные, объявленные и инициализированные в основной программе, которая вызывает эту DLL. Как это сделать? И можно ли в функциях DLL изменять значения этих глобальных переменных--и если да, то как?

PM MAIL   Вверх
baldina
Дата 26.1.2015, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



Цитата(erslgoeirjh @  26.1.2015,  14:44 Найти цитируемый пост)
Я хочу в функциях моей DLL использовать глобальные переменные, объявленные и инициализированные в основной программе, которая вызывает эту DLL. Как это сделать?

dll про вашу основную программу ничего не знает, так что напрямую никак. но в интерфейс dll можно включить функцию, которой будете передавать адрес переменной из основной программы.

Цитата(erslgoeirjh @  26.1.2015,  14:44 Найти цитируемый пост)
Нужно ли в моём классе MyClass объявлять его данные и методы как static, или можно обойтись без этого?

не нужно. к dll это не относится.
PM MAIL   Вверх
erslgoeirjh
Дата 26.1.2015, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 16.12.2005

Репутация: нет
Всего: нет



Цитата(baldina @ 26.1.2015,  16:17)
Цитата(erslgoeirjh @  26.1.2015,  14:44 Найти цитируемый пост)
Я хочу в функциях моей DLL использовать глобальные переменные, объявленные и инициализированные в основной программе, которая вызывает эту DLL. Как это сделать?

dll про вашу основную программу ничего не знает, так что напрямую никак. но в интерфейс dll можно включить функцию, которой будете передавать адрес переменной из основной программы.

То есть надо написать что-то вроде

Код

MyDllFunction1(int *ivar, long *lvar, float *fvar, long double *ldvar)
{
    // тело функции;
}


?
(Где ivar, lvar, fvar, ldvar--указатели на соответствующие переменные в основной программе).

И надо ли эти указатели ivar, lvar, fvar, ldvar объявлять глобальными переменными в файлах моего DLL?
И стоит ли использовать слово extern при их объявлении?

PM MAIL   Вверх
baldina
Дата 26.1.2015, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



Код

// dll
int *x_, *y_;
__declspec(dllexport) SetVars(int *x, int *y) {
  x_ = x;
  y_ = y;
}

// main program
int x, y;
...
SetVars(&x, &y);

PM MAIL   Вверх
erslgoeirjh
Дата 26.1.2015, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 16.12.2005

Репутация: нет
Всего: нет



Ясно. Последний вопрос--код:

Код

int *x_, *y_;
__declspec(dllexport) SetVars(int *x, int *y) {
  x_ = x;
  y_ = y;
}


следует поместить в файл MyFirstDll.h ?

PM MAIL   Вверх
vol4ek
Дата 26.1.2015, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


конь в пальто
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 1.5.2011
Где: Минск

Репутация: -1
Всего: 0



smile  и это работает?

Добавлено через 6 минут и 20 секунд
там AfxInitExtensionModule ни о чем не говорит?  смысл этой dll если вся реализация в файле MyFirstDll.h?
PM MAIL ICQ   Вверх
erslgoeirjh
Дата 27.1.2015, 08:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 16.12.2005

Репутация: нет
Всего: нет



Цитата(vol4ek @ 26.1.2015,  19:06)
smile  и это работает?

Добавлено @ 19:12
там AfxInitExtensionModule ни о чем не говорит?  смысл этой dll если вся реализация в файле MyFirstDll.h?

Это просто тестовое DLL и тестовая программа, которая вызывает это DLL.

PM MAIL   Вверх
baldina
Дата 27.1.2015, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



erslgoeirjh, в MyFirstDll.cpp
а в MyFirstDll.h должно быть объявление функции
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0482 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.