Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как импортировать класс из DLL?

20K
09 сентября 2006 года
ch_andr
5 / / 30.08.2006
Доброго времени суток!
Как импортировать класс из DLL? Или как создать обьект, класс которго содержится в DLL?
DLL подключена динамически с помощью LoadLibrary.
Функцией GetProcAddress я получаю адреса функций, методов, и по-моему классов.
Здесь представлен код с помощью которого можно использовать функцию, которая содержится в DLL.

//My.cpp//файл приложения
::
hMyDll=::LoadLibrary("tstdll");//получаем адресс DLL
typedef int (WINAPI *PFN_MyFunction)(int);//не знаю
PFN_MyFunction pfnMyFunction;
pfnMyFunction=(PFN_MyFunction)::GetProcAddress(hMyDll,"MyFunction");//получаем адресс функции
int iCode=(*pfnMyFunction)(4);//используем функцию!!!
FreeLibrary(hMyDll);
::

Подскажите пожалуйста с помощью чего и как, по аналогии представленного кода, можно создать обьект или класс, если известен адресс класса в DLL.
723
10 сентября 2006 года
Tommy
78 / / 13.10.2002
Совершенно ясно, что всё что видно из Dll - это куча функций, поэтому информацию от типе от туда средствами языка никак не достать. Потому ответ - COM, тебя никто не заставляет регистрировать и так далее, просто надо использовать эти самые запросы интерфейсов и т.д. Но это я так понимаю, тебе не подходит, правильно, тебе, я так понимаю, нужно извлекать информацию от типе. Но, по-моему с обычной Dll тебе такого не сделать. Короче говоря надо использовать COM. Но если так уж надо скинь мне по мылу: [email]TommyAlice@gmail.ru[/email], или в асю: 580758, я там всё что знаю расскажу.
7.8K
11 сентября 2006 года
littlefrankie
57 / / 23.08.2006
Переходи на Visual Studio 2003/2005 Там всё просто. Объявляешь класс как public и он доступен во всех assemblies то есть сборках. А com по моему шняга. Хотя я чес говоря в нем не пробовал.
395
11 сентября 2006 года
RelB
367 / / 09.11.2002
[QUOTE=littlefrankie]Переходи на Visual Studio 2003/2005 Там всё просто. Объявляешь класс как public и он доступен во всех assemblies то есть сборках. А com по моему шняга. Хотя я чес говоря в нем не пробовал.[/QUOTE]COM - шняга? Это еще почему?
10
11 сентября 2006 года
Freeman
3.2K / / 06.03.2004
[QUOTE=RelB]COM - шняга? Это еще почему?[/QUOTE]
Не поддерживает межмодульного наследования, например.
395
11 сентября 2006 года
RelB
367 / / 09.11.2002
[QUOTE=Freeman]Не поддерживает межмодульного наследования, например.[/QUOTE]Всмысле? Можно поподробней, что ты имеешь ввиду? По поводу вопроса, забыл ответить, у тебя dll сторонняя что-ли раз ты используещь LoadLibrary? Если dll своя, т.е. есть исходники, то создать эксземпляр класса который находится в dll проще простого.
1. Делаешь этот класс экспортируемым, а именно class __declspec(dllexport) Имя_класса
2. Инклюдишь его хидер там где он используется.
3. Прописываешь в свойствах линкера в additional dependencies: имя_длл.lib (lib полюбому должен будет создастся при сборке проекта длл-ки)

Вот и все
723
11 сентября 2006 года
Tommy
78 / / 13.10.2002
На счёт COM'а:
1. Это, компонентное, так сказать программирование поэтому там нет наследования реализации вообще, а оно для компоненттов типа COM вообще не нужно - используйте наследование интерфеса.

На счёт Visual Studio:
Там же используеться .NET, а раз так то и говорить нечего - ясно же что автору темы не это нужно.

На счёт __declspec - это долбанное Microsoft Specific, поэтому там с dllexport для классов запаришся. Вообще обычная Dll экпортирет только функции и всё остальное это уже не то.
20K
12 сентября 2006 года
ch_andr
5 / / 30.08.2006
[QUOTE=RelB]Всмысле? Можно поподробней, что ты имеешь ввиду? По поводу вопроса, забыл ответить, у тебя dll сторонняя что-ли раз ты используещь LoadLibrary? Если dll своя, т.е. есть исходники, то создать эксземпляр класса который находится в dll проще простого.
1. Делаешь этот класс экспортируемым, а именно class __declspec(dllexport) Имя_класса
2. Инклюдишь его хидер там где он используется.
3. Прописываешь в свойствах линкера в additional dependencies: имя_длл.lib (lib полюбому должен будет создастся при сборке проекта длл-ки)[/QUOTE]

Я использую LoadLibrary для того чтобы по нужде загружать и выгружать ДЛЛ, а не с запуском-остановом приложения (в случае длл.lib) из-за ограничения ресурсов (оперативки).

А насчет СОМ - это темный лес для меня, а времени как всегда в обрез. Но думаю придется изучить.

[QUOTE=Tommy]На счёт __declspec - это долбанное Microsoft Specific, поэтому там с dllexport для классов запаришся. Вообще обычная Dll экпортирет только функции и всё остальное это уже не то[/QUOTE]

Тогда каким образом используется класс из ДЛЛ в случае неявной загрузки(длл.lib). По идее ДЛЛ одна, адреса те же, однако при неявной загрузке можем работать с классом, при явной нет? а с функциями хоть как можно! Обьясните в чем разница?
398
12 сентября 2006 года
Alexandoros
630 / / 21.10.2005
ch_andr Задайся вопросом :"Нахрона оно надо?" И все пройдет/(решится через ф-ции)
395
12 сентября 2006 года
RelB
367 / / 09.11.2002
[QUOTE=ch_andr]Я использую LoadLibrary для того чтобы по нужде загружать и выгружать ДЛЛ, а не с запуском-остановом приложения (в случае длл.lib) из-за ограничения ресурсов (оперативки).

А насчет СОМ - это темный лес для меня, а времени как всегда в обрез. Но думаю придется изучить.



Тогда каким образом используется класс из ДЛЛ в случае неявной загрузки(длл.lib). По идее ДЛЛ одна, адреса те же, однако при неявной загрузке можем работать с классом, при явной нет? а с функциями хоть как можно! Обьясните в чем разница?[/QUOTE]Механизм-то по сути скорее всего один и тот-же, хотя и не факт. Методы класса будут в dll-ке, но только как отдельные функции, типа MyClass::MyClass() - это типа конструктор и следовательно ни как линкеру бедному не будет понятно, что они то и есть, те самые, которые нужно вызывать при обращении к методам MyClass. А вот если lib файл ему указать, то он все будет знать :)

Немного запутанно получилось... :)
395
13 сентября 2006 года
RelB
367 / / 09.11.2002
[QUOTE=RelB]Механизм-то по сути скорее всего один и тот-же, хотя и не факт. Методы класса будут в dll-ке, но только как отдельные функции, типа MyClass::MyClass() - это типа конструктор и следовательно ни как линкеру бедному не будет понятно, что они то и есть, те самые, которые нужно вызывать при обращении к методам MyClass. А вот если lib файл ему указать, то он все будет знать :)

Немного запутанно получилось... :)[/QUOTE]Кстати, есть еще один способ. Объявляешь базовый интерфейс для своего класса, помещаешь его в хидер, который доступен для твоего приложения, создаешь в дллельке экспортирумую функцию MyClass_CreateInstance, которая возвращает указатель на интерфейс IMyClass и юзаешь методы этотго интерфейса, вот и все.

Например так:
Код хидера:
 
Код:
struct IMyClass
{
   virtual void Method1() = 0;
   virtual void Method2() = 0;
   virtual void AddRef() = 0;
   virtual void Release() = 0;
}

Код класса и функции:
Код:
class MyClass : public IMyClass
{
private:
  .
  .
  int refCount_;
  .
public:
  MyClass() : refCount(0) { ... }
  .
  .
  virtual void Method1();
  virtual void Method2();
  virtual void AddRef() { refCount_ ++; }
  virtual void Release() { if(!--refCount_) delete this; }
}

__declspec(ddlexport) IMyClass* MyClass_CreateInstance()
{
   return new MyClass();
}

Теперь, как этим классом пользоваться, допустим ты уже знаешь адрес функции MyClass_CreateInstance.
Код:
void SomeFunction()
{
  .
  .
  .
  IMyClass* pMyClass = MyClass_CreateInstance();
  pMyClass->AddRef();
  .
  .
  .
  pMyClass->Release();
}
324
13 сентября 2006 года
AndreySar
532 / / 01.08.2004
AFX_EXT_CLASS
20K
13 сентября 2006 года
ch_andr
5 / / 30.08.2006
[QUOTE=Alexandoros]ch_andr Задайся вопросом :"Нахрона оно надо?" И все пройдет/(решится через ф-ции)[/QUOTE]
Это не мне надо, это задание такое!
20K
13 сентября 2006 года
ch_andr
5 / / 30.08.2006
Все! Помогли люди добрые - знающие.
Вот пример кода, как создавать обьект, класс которого в ДЛЛ, которая загружается динамически явно(через LoadLibrary).

MyClassInDll.h// при компилировании файл также подключается к приложению
Код:
#pragma once
#ifndef _DLL_PROJ_
#define _DLL_LIB  __declspec(dllimport)
#else
#define _DLL_LIB  __declspec(dllexport)
#endif // !defined(_DLL_PROJ_)
::
class _DLL_LIB CtstVrt
{
private:
    TvrtState VrtData;
public:
    CtstVrt(void);
    virtual int InitVrt(Tinit &, dword );
    virtual int RunVrt(TinpData &, ToutData &, dword );
    virtual int PauseVrt(dword );
    virtual int ExitVrt(int &);
    ~CtstVrt(void);
};

extern "C"
{  
    _DLL_LIB  void *CreateCtstVrt();
    _DLL_LIB  void FreeCtstVrt();
}



MyExe.h
Код:
::
///========= Грузим DLL!!! =========================
if((hVrtDll=::LoadLibrary("MyClassInDll.dll"))==NULL)
    { //    /* не удалось загрузить DLL */
    }
    else
    { /* приложение имеет право пользоваться функциями DLL через hVrtDll*/
    }
pfnCreateCtstVrt = (PFN_CreateCtstVrt)::GetProcAddress(hVrtDll,"CreateCtstVrt");
pfnFreeCtstVrt = (PFN_FreeCtstVrt)::GetProcAddress(hVrtDll,"FreeCtstVrt");
           
CtstVrt *pClass=(CtstVrt *)pfnCreateCtstVrt();//создаем объект
pClass->InitVrt(initDat,Time);// пример вызова метода
::
 //------- Выгружаем DLL-------------------------
 if( hVrtDll!=0 ) ::FreeLibrary(hVrtDll);
::
20K
14 сентября 2006 года
Xadja
7 / / 14.09.2006
Народ, решил не постить новую тему, а спросить в этой. Я конечно не знаток в С++ (занимаюсь шарпом), но так для общего развития решил враппер простейший написать unmanaged->managed.
Вот код unmanaged .h:

#ifdef UNMANAGED_EXPORT
#define UNMANAGED_API __declspec(dllexport)
#else
#define UNMANAGED_API __declspec(dllimport)
#endif

class UNMANAGED_API CUnmanaged
{
public:
int nValue;
CUnmanaged();
};

.CPP:
#include "stdafx.h"
#include "Unmanaged.h"

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}


CUnmanaged::CUnmanaged()
{
nValue = 5;
}

И managed .h:
#include "Unmanaged.h"

public __gc class Managed
{
public:
int nValue;
Managed();
private:
CUnmanaged __nogc* p;

};

.CPP:
#include "stdafx.h"
#include "Managed.h"

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}

Managed::Managed()
{
p = new CUnmanaged();
nValue=p->nValue;
}

Вроде все путем, но в итоге получаю такую ошибку:
Error 2 error LNK2028: unresolved token (0A000009) "public: __thiscall CUnmanaged::CUnmanaged(void)" (??0CUnmanaged@@$$FQAE@XZ) referenced in function "public: __clrcall Managed::Managed(void)" (??0Managed@@$$FQ$AAM@XZ) Managed.obj
20K
14 сентября 2006 года
Xadja
7 / / 14.09.2006
Всем спасибо за внимание, я просто либу не подключил :) уже все заработало :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог