Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
14 / 7 / 0
Регистрация: 20.09.2009
Сообщений: 89
1

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

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

Author24 — интернет-сервис помощи студентам
Имеется созданная библиотека, включающая небольшой класс, как правильно реализовать доступ в программе к элементам данного класса, реализованным в 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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.09.2009, 05:57
Ответы с готовыми решениями:

Импорт класса из C++ в C#
Есть класс (шаблонный), написанный на С++. Необходимо его импортировать в C#. Я пробовал собирать...

Импорт класса ошибка
Где здесь ошибка? вот пакет: package samples { public class SampleCode { ...

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

Импорт С# класса из DLL в С++/CLI
имеется HelloWorld на Шарпе, приведите пожалуйста пример его использования в консольном С++/CLR,...

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

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

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

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

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

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

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

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

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

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

Добавлено через 1 минуту
тьфу ты тут ещё страница, жаль пост удалить нельзя...
0
14 / 7 / 0
Регистрация: 20.09.2009
Сообщений: 89
23.09.2009, 20:39  [ТС] 20
Ну что кто-нибудь знает по каким правилам имя функции искажается линкером очень нужно!!!!
0
23.09.2009, 20:39
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.09.2009, 20:39
Помогаю со студенческими работами здесь

Импорт класса из другого файла
Кароче Мне необходимо прописать действие при нажатии кнопки. Интерфейс сделал в QtDesigner, файл...

Импорт класса из другого проекта
Подскажите, пожалуйста, каким образом я могу импортировать класс Java, который был объявлен в...

Как сделать импорт класса?
Ситуация такая: Есть Class1 он лежит в package1.package2.Class1 Есть Class2 он лежит в Root т.е....

Импорт статических методов класса Math.
Хочу импортировать методы и писать так: double n = sqrt(4.0); Делаю: package test; //import...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru