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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.67
NightmareCode
14 / 7 / 1
Регистрация: 20.09.2009
Сообщений: 89
#1

Импорт элементов класса в программу - C++

20.09.2009, 05:57. Просмотров 1500. Ответов 23
Метки нет (Все метки)

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

В приложении-dll имеются, следующие файлы:
stdafx.h
targetver.h
dllmain.cpp-точку входа в dll
вот код VirtualLibraryDLL_beta1.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma once
 
class VirtualFuncs
{
    char* sampleName;
public:
    VirtualFuncs(void)
    {
        sampleName="Renault";
    }
 
    virtual ~VirtualFuncs(void)
    {
    }
    char* CALLBACK GetSampleName();
    virtual char* CALLBACK GetVirtSampleName();
};
Вот код VirtualLibraryDLL_beta1.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
#include "stdafx.h"
#include "VirtualLibraryDLL_beta1.h"
 
extern "C" char* CALLBACK VirtualFuncs::GetSampleName()
{
    return this->sampleName;
}
extern "C" char* CALLBACK VirtualFuncs::GetVirtSampleName()
{
    return sampleName;
}
Вот VirtualLibraryDLL.def
LIBRARY "VirtualLibraryDLL_beta1"

EXPORTS
GetSampleName
GetVirtSampleName
Вот само приложение. использующая данный класс. реализованный в 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
26
27
28
29
30
31
32
33
34
35
#include "windows.h"
 
int main()
{
    HMODULE hLib;
    hLib=LoadLibrary(L"VirtualLibraryDLL_beta1.dll");
    if(hLib!=NULL)
    {
        char* (*pGetNameSampleVirt)();
        (FARPROC&)pGetNameSampleVirt=GetProcAddress(hLib, "GetVirtSampleName");
        if(!pGetNameSampleVirt)
        {
            return -2;
        }
        else
        {
            char* strNameVirt=pGetNameSampleVirt();
        }
        char* (*pGetNameSample)();
        (FARPROC&)pGetNameSample=GetProcAddress(hLib, "GetSampleName");
        if(!pGetNameSample)
        {
            return -3;
        }
        else
        {
            char* strName=pGetNameSample();
        }
        FreeLibrary(hLib);
    }//if(hLib!=NULL)
    else
    {
        MessageBox(NULL, L"Невозможно загрузить DLL", L"DLL не найдена", MB_OK);
    }
}
Добавлено через 3 минуты
У меня есть предположение что надо помимо загрузки dll описывать файл-определения класса, а то как реализовать доступ к методом класса без самого объекта.
Или как-то можно описать сам конструктор, создающий объект в def-файле?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.09.2009, 05:57
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Импорт элементов класса в программу (C++):

Создать объявление класса и разработать программу-драйвер, которая продемонстрирует работу класса. - C++
Класс Triangle (треугольник). Класс хранит Декартовы координаты трех углов треугольника. Конструктор принимает три группы координат. Должны...

Составьте программу, выводящую на экран сообщения об отличниках класса, о средней успеваемости учащихся класса - C++
Опишите, используя структуру записи, школьный журнал. Предусмотрите в записи поля для хранения информации о фамилии учащегося, предмете,...

создать программу с использованием класса - C++
Написать программу, в которой используется класс myclass для задания значений "а" для объектов "ob1" и "ob2" и вывода на экран этих...

Переделать программу с использованием шаблона класса - C++
Организовать программу с помощью Шаблона класса. class ttt { char *str; public: ttt(); bool operator >= (ttt...

написать программу с описанием класса Employee - C++
написать программу с описанием класса Employee. Класс должен содержать поля: фамилия, имя, отчество, дата рождения в формате (XX/YY/ZZZZ),...

вектор элементов класса - C++
Подскажите пожалуйста,как сделать вектор элементов класса,особенно .push_back(?)

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
NightmareCode
14 / 7 / 1
Регистрация: 20.09.2009
Сообщений: 89
20.09.2009, 23:37  [ТС] #2
Ладно смотрю никто не может ответить на этот вопрос, тогда спрошу о другом.

Как создается линкером имя вида ??0VirtualFuncs@@QAE@XZ и где его можно определить?

Для того чтобы затем явно определить его в def-файле таким образом
VirtualFuncs = ??0VirtualFuncs@@QAE@XZ PRIVATE
Необходимо для явного определения конструктора в последующем использовании.
0
kravam
быдлокодер
1695 / 882 / 45
Регистрация: 04.06.2008
Сообщений: 5,459
21.09.2009, 00:12 #3
Извини меня, но я не понял такую деталь
Насколько я знаю, файл *dll это исполняемый файл. Бинарный по факту. Загрузчик смотрит разные значения в его заголовке (размеры секций, адреса, куда загрузить и прочее) и, согласно им, загружает .dll файл в оперативную память.

Твой же файл VirtualLibraryDLL_beta1.dll

он не бинарный файл. Не исполняемый. Он даже не файл- он... несколько файлов. Текстовых.
Руководствовался исключительно желанием помочь.
Извини, если что не так. Буду рад любым опровержениям.
0
NightmareCode
14 / 7 / 1
Регистрация: 20.09.2009
Сообщений: 89
21.09.2009, 00:35  [ТС] #4
Цитата Сообщение от kravam Посмотреть сообщение
Извини меня, но я не понял такую деталь
Насколько я знаю, файл *dll это исполняемый файл. Бинарный по факту. Загрузчик смотрит разные значения в его заголовке (размеры секций, адреса, куда загрузить и прочее) и, согласно им, загружает .dll файл в оперативную память.

Твой же файл VirtualLibraryDLL_beta1.dll

он не бинарный файл. Не исполняемый. Он даже не файл- он... несколько файлов. Текстовых.
Руководствовался исключительно желанием помочь.
Извини, если что не так. Буду рад любым опровержениям.
Я комплирую получаю dll-файл, затем потом использую его в программе-консоли(exe-файл).
Так моя главная проблема это как получить указатель на конструктор класса. DLL содержит класс!
Вот в чем главная проблема.

P.S. DLL-является исполняемым бинарным файлом это всем понятно.
0
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
21.09.2009, 00:46 #5
google exporting classes in C++

там все довольно подробно описано. если не получится разобраться - сообщите, я завтра попробую простенький примерчик привести.
0
gorin
207 / 14 / 2
Регистрация: 18.08.2009
Сообщений: 571
21.09.2009, 18:25 #6
novi4ok, А она вабще верная!!
0
NightmareCode
14 / 7 / 1
Регистрация: 20.09.2009
Сообщений: 89
21.09.2009, 22:05  [ТС] #7
Цитата Сообщение от gorin Посмотреть сообщение
novi4ok, А она вообще верная!!
Что верная? Да DLL и EXE компилится однако использовать это невозможно(ошибка этапа выполнения), так как неизвестно,
как создать экземпляр класса VirtualFuncs, поскольку в def-файле я не знаю как объявить конструктор класса в открытую VirtualFuncs в def-файле определять нельзя, можно только, используя декорированное имя вида
Constructor=??0VirtualFuncs@@QAE@XZ PRIVATE
(неверно, не знаю как правильно создать или определить декорированное имя)
0
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
21.09.2009, 22:52 #8
почитать не удалось? понять не удалось? все еще актуально?
0
NightmareCode
14 / 7 / 1
Регистрация: 20.09.2009
Сообщений: 89
22.09.2009, 10:26  [ТС] #9
Главный мой вопрос теперь по каким правилам декорируется имя линкером?
0
GAV_13
81 / 81 / 4
Регистрация: 14.09.2009
Сообщений: 252
22.09.2009, 10:34 #10
Цитата Сообщение от NightmareCode Посмотреть сообщение
C++
1
hLib=LoadLibrary(L"VirtualLibraryDLL_beta1.dll");
А буковка L в этой функции зачем? о_О
0
NightmareCode
14 / 7 / 1
Регистрация: 20.09.2009
Сообщений: 89
22.09.2009, 10:41  [ТС] #11
Цитата Сообщение от GAV_13 Посмотреть сообщение
А буковка L в этой функции зачем? о_О
Потому что класс LPCWSTR, а перед ним всегда должна быть литера L.

P.S. Не по теме.
0
GAV_13
81 / 81 / 4
Регистрация: 14.09.2009
Сообщений: 252
22.09.2009, 11:09 #12
Может и не по теме, но вызываеццо это так:
C++
1
2
3
4
5
6
int main()
{
    // явным образом проецируем DLL на адресное пространство нашего процесса
    HMODULE hModule = LoadLibrary("mydll.dll");
    // проверяем успешность загрузки
}
0
NightmareCode
14 / 7 / 1
Регистрация: 20.09.2009
Сообщений: 89
22.09.2009, 11:13  [ТС] #13
Цитата Сообщение от GAV_13 Посмотреть сообщение
Может и не по теме, но вызываеццо это так:
C++
1
2
3
4
5
6
int main()
{
    // явным образом проецируем DLL на адресное пространство нашего процесса
    HMODULE hModule = LoadLibrary("mydll.dll");
    // проверяем успешность загрузки
}
У тебя старая версия файла windows.h в VS2008 в LoadLibrary, класс LPCWSTR, а не char*
Поэтому у меня компилится, а у тебя нет О_о
0
GAV_13
81 / 81 / 4
Регистрация: 14.09.2009
Сообщений: 252
22.09.2009, 11:22 #14
Цитата Сообщение от NightmareCode Посмотреть сообщение
имя вида ??0VirtualFuncs@@QAE@XZ и где его можно определить?
Копать кажись в эту сторону:
Декорирование имен усложняет экспорт функций из DLL, написанной на языке C++. Например, в использующем DLL приложении попытка получить адрес функции MyFunc закончится неудачей - вызов GetProcAddress("MyFunc") вернет NULL, потому что компоновщик честно поместит в секцию экспорта DLL декорированное имя ?MyFunc@@YAHHHPAD@Z вместо ожидаемого MyFunc.

Чтобы избежать этого, необходимо объявлять все экспортируемые функции с модификатором extern "C" - тогда компилятор не будет искажать имя функции.
Для экспорта из DLL нескольких функций без декорирования их имен можно поместить объявления в блок, помеченный этим модификатором:
C++
1
2
3
4
5
6
extern "C"
{
  int Func1();
  const char* Func2(const char*);
  void Func3(int, int);
}
Имена функций Func1, Func2, Func3 будут экспортированы без искажений. К сожалению, этот прием нельзя применять для экспорта из DLL перегруженных функций, равно как и для экспорта функций классов.
Добавлено через 2 минуты
правда, не знаю как это будет под VS2008...
0
NightmareCode
14 / 7 / 1
Регистрация: 20.09.2009
Сообщений: 89
22.09.2009, 11:46  [ТС] #15
У меня есть идея определить все функции, как чисто виртуальные и реализовать в интерфейсе
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#else
 
struct IMyClassLibrary
{
    virtual  int Func1()=0;
    virtual  const char* Func2(const char*)=0;
    virtual  void Func3(int, int)=0;
}
 
typedef IMyClassLibrary* MyClassHandle;
Затем создать производный класс от этого интерфейса и отдельно реализовать функцию, выполняющую роль конструктора что-то вроде.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyClassImpl:public IMyClassLibrary
{
    //TODO. Все объявления функций
}
//реализация функций
//...
//Отдельная функция для создания объекта этого класса
#pragma comment(linker, /export:MyClassImpl=_MyClassImpl@0")
//Где _MyClass@0, предположительное декорированное имя создаваемое линкером!
 
MyClassHandle APIENTRY MyClassImpl()
{
    return new MyClassImpl;
}
Добавлено через 5 минут
Цитата Сообщение от GAV_13 Посмотреть сообщение
Чтобы избежать этого, необходимо объявлять все экспортируемые функции с модификатором extern "C" - тогда компилятор не будет искажать имя функции.
Необязательно объявлять с модификатором extern "C", можно в def-файле явно определить декорированному имени недекорированное имя
недекорированное_имя=декорированное_имя PRIVATE
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.09.2009, 11:46
Привет! Вот еще темы с ответами:

Массив элементов класса - C++
Есть такой Класс class NEURON { private: double *pdInDate; double dOutDate; double *pdWeightIn; int iSumIn; ...

Как переписать программу используя понятие класса - C++
У меня проблемы с написанием программ используя классы. Помогите переписать программу, написанную с использованием Vector в прогу с...

Напишите программу, используя методы класса string - C++
Прошу помочь с простенькой задачей :) 9. Напишите программу, используя методы класса string.

Удаление из массива элементов класса - C++
пытаюсь разобраться с классами, но особо не получается..да и вечное "скорее сдать" не особо оставляет время для того, чтобы понять все до...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
22.09.2009, 11:46
Ответ Создать тему
Опции темы

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