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

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

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

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

20.09.2009, 05:57. Просмотров 1459. Ответов 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-файле?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.09.2009, 05:57     Импорт элементов класса в программу
Посмотрите здесь:

C++ Создать объявление класса и разработать программу-драйвер, которая продемонстрирует работу класса.
вектор элементов класса C++
Удаление из массива элементов класса C++
Как переписать программу используя понятие класса C++
C++ создать программу с использованием класса
C++ написать программу с описанием класса Employee
C++ Напишите программу, используя методы класса string
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
NightmareCode
14 / 7 / 1
Регистрация: 20.09.2009
Сообщений: 89
20.09.2009, 23:37  [ТС]     Импорт элементов класса в программу #2
Ладно смотрю никто не может ответить на этот вопрос, тогда спрошу о другом.

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

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

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

он не бинарный файл. Не исполняемый. Он даже не файл- он... несколько файлов. Текстовых.
Руководствовался исключительно желанием помочь.
Извини, если что не так. Буду рад любым опровержениям.
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-является исполняемым бинарным файлом это всем понятно.
novi4ok
550 / 503 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
21.09.2009, 00:46     Импорт элементов класса в программу #5
google exporting classes in C++

там все довольно подробно описано. если не получится разобраться - сообщите, я завтра попробую простенький примерчик привести.
gorin
207 / 14 / 2
Регистрация: 18.08.2009
Сообщений: 571
21.09.2009, 18:25     Импорт элементов класса в программу #6
novi4ok, А она вабще верная!!
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
(неверно, не знаю как правильно создать или определить декорированное имя)
novi4ok
550 / 503 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
21.09.2009, 22:52     Импорт элементов класса в программу #8
почитать не удалось? понять не удалось? все еще актуально?
NightmareCode
14 / 7 / 1
Регистрация: 20.09.2009
Сообщений: 89
22.09.2009, 10:26  [ТС]     Импорт элементов класса в программу #9
Главный мой вопрос теперь по каким правилам декорируется имя линкером?
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 в этой функции зачем? о_О
NightmareCode
14 / 7 / 1
Регистрация: 20.09.2009
Сообщений: 89
22.09.2009, 10:41  [ТС]     Импорт элементов класса в программу #11
Цитата Сообщение от GAV_13 Посмотреть сообщение
А буковка L в этой функции зачем? о_О
Потому что класс LPCWSTR, а перед ним всегда должна быть литера L.

P.S. Не по теме.
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");
    // проверяем успешность загрузки
}
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*
Поэтому у меня компилится, а у тебя нет О_о
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...
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
GAV_13
81 / 81 / 4
Регистрация: 14.09.2009
Сообщений: 252
22.09.2009, 12:04     Импорт элементов класса в программу #16
Тогда в чем сложность? в получении декорированного имени? Это можно сделать, воспользовавшись утилитой dumpbin.exe с ключом -exports из состава Visual Studio.
novi4ok
550 / 503 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
22.09.2009, 12:09     Импорт элементов класса в программу #17
Цитата Сообщение от NightmareCode Посмотреть сообщение
Главный мой вопрос теперь по каким правилам декорируется имя линкером?
а на хрена это нужно?
NightmareCode
14 / 7 / 1
Регистрация: 20.09.2009
Сообщений: 89
22.09.2009, 12:17  [ТС]     Импорт элементов класса в программу #18
Цитата Сообщение от GAV_13 Посмотреть сообщение
Тогда в чем сложность? в получении декорированного имени? Это можно сделать, воспользовавшись утилитой dumpbin.exe с ключом -exports из состава Visual Studio.
Я пользуюсь другой утилитой, тоже выдает хороший список декорированных имен функций.
Цитата Сообщение от novi4ok Посмотреть сообщение
А зачем тебе это нужно?
Нужно
Adler
78 / 78 / 3
Регистрация: 07.05.2009
Сообщений: 316
22.09.2009, 23:53     Импорт элементов класса в программу #19
Цитата Сообщение от GAV_13 Посмотреть сообщение
А буковка L в этой функции зачем? о_О
это злосный макрос от мелкософта в студии. Используется для перевода сторок из ансив в юникод на этапе компиляции.

Добавлено через 1 минуту
тьфу ты тут ещё страница, жаль пост удалить нельзя...
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.09.2009, 20:39     Импорт элементов класса в программу
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
NightmareCode
14 / 7 / 1
Регистрация: 20.09.2009
Сообщений: 89
23.09.2009, 20:39  [ТС]     Импорт элементов класса в программу #20
Ну что кто-нибудь знает по каким правилам имя функции искажается линкером очень нужно!!!!
Yandex
Объявления
23.09.2009, 20:39     Импорт элементов класса в программу
Ответ Создать тему
Опции темы

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