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

Ваш аккаунт

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

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

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

dll и классы (dll-расширение)

8.1K
30 сентября 2004 года
MegaBrain
7 / / 30.09.2004
Мне нужно явно(!) подключить dll c классом, но я не знаю как в таком случае импортировать переменные! классов:
#include <windows.h>
class MyDllClass{
public:
void (*Demo) (char *str);
};
main()
{
HINSTANCE h=LoadLibrary("DllClass.dll");
MyDllClass Obj;
Obj.Demo=(void (*) (char *str))
GetProcAddress(h,"Demo");
//выполняем конструктор
Obj.Demo("Test");
}
Т.е. после демангливания (через Def), как обратиться к переменной объекта класса (для каждого своя!)? Или нужно обязательно создавать
функции типа Get/Set? Вообще нигде! не написано про обращение к переменным dll (импорт из dll) при явной! загрузке (везде - только про функции - GetProcAddress). При неявной загрузке - проблем нет!
3
30 сентября 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by MegaBrain
Мне нужно явно(!) подключить dll c классом, но я не знаю как в таком случае импортировать переменные! классов:
#include <windows.h>
class MyDllClass{
public:
void (*Demo) (char *str);
};
main()
{
HINSTANCE h=LoadLibrary("DllClass.dll");
MyDllClass Obj;
Obj.Demo=(void (*) (char *str))
GetProcAddress(h,"Demo");
//выполняем конструктор
Obj.Demo("Test");
}
Т.е. после демангливания (через Def), как обратиться к переменной объекта класса (для каждого своя!)? Или нужно обязательно создавать
функции типа Get/Set? Вообще нигде! не написано про обращение к переменным dll (импорт из dll) при явной! загрузке (везде - только про функции - GetProcAddress). При неявной загрузке - проблем нет!



1. Непонятно почему вопрос в разделе Win32API.
2. Что значит "демангливания"? Пишите либо по-русски, либо по-английски.
3. Экземпляр класса находится в памяти, а не в DLL. Так что мешает обращаться к его полям? Ты же сделал это с полем Demo
Obj.Demo = ............

Кстати, правильно ли ты понимаешь термин "явная загрузка". Явная, это как раз через LoadLibrary с последующим GetProcAddress.

8.1K
01 октября 2004 года
MegaBrain
7 / / 30.09.2004
Вопрос относится именно к WinAPI (процессы, потоки, объекты ядра, дин. библиотеки и др.), непосредственно к DLL (не к COM).
Так вот: в DLL можно экспортировать класс, и потом
даже наследовать от него-если подключиться неявно
(сослаться на LIB-ку). Т.к. компилятор разукрашивает (манглит/mangle) имена функций, то для того, чтобы обращаться к dll из другой среды, нужно это предотвратить с помощью DEF-файла. После этого функции теряют связи с классом, да даже и без демангливания я не знаю как обращаться к классу при явной загрузке dll (нет же функции GetClassAddress/GetClass или типа того). То ли дело-динамическая загрузка сборок в .NET - можно все что угодно сделать! Неужели нельзя собрать класс по кусочкам (с нестатическими! переменными!) Типа такого:
class dllclass{...};
...
h=LoadLibrary(...);
...
dllclass obj=CreateObjectInProcessMemoryByClassNameWhichDefinedInExternDLL(h,"dllclass"...)
...
Или быть может я многого хочу, может существуют ограничения? Т.Е. если укажу для каждого объекта (как в примере выше) указателями на одни и теже функции описанные в DLL, то меня это не устроит - ведь они должны работать с полями конкретного экземпляра класса! (как до них добраться - это уже второй вопрос)
424
01 октября 2004 года
(C)dragon
307 / / 04.12.2002
Можно сделать DLL с определением всех функций класса, эти функции должны экспортироваться. Потом надо сделать заголовочный файл с этим классом, естесственно не включая определения функций. При линковке все созданные компилятором вызовы, включая всякие конструкторы и деструкторы привяжутся к dll. Но это только для статической линковки с DLL, использовать LoadLibrary никак не получится.

Хотя все функции сделать виртуальными и экспортировать таблицу виртуальных методов, а потом явно её перезаписывать в экземпляре объекта, может что и получится. Только чтобы компилятор не ругался, все функции должны присутствовать в виде пустышек.
3
02 октября 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by MegaBrain
Вопрос относится именно к WinAPI (процессы, потоки, объекты ядра, дин. библиотеки и др.), непосредственно к DLL (не к COM).


Я кажется понял суть твоего вопроса. И все же считаю, что он не относится непосредственно к Win32 API, а скорее к специфике используемого компилятора.

Цитата:
Originally posted by MegaBrain

Так вот: в DLL можно экспортировать класс, и потом
даже наследовать от него-если подключиться неявно
(сослаться на LIB-ку). Т.к. компилятор разукрашивает (манглит/mangle) имена функций, то для того, чтобы обращаться к dll из другой среды, нужно это предотвратить с помощью DEF-файла.


Спасибо за ликбез, но тебе достаточно было употребить слово "декорирование".

Цитата:
Originally posted by MegaBrain

После этого функции теряют связи с классом, да даже и без демангливания я не знаю как обращаться к классу при явной загрузке dll (нет же функции GetClassAddress/GetClass или типа того). То ли дело-динамическая загрузка сборок в .NET - можно все что угодно сделать! Неужели нельзя собрать класс по кусочкам (с нестатическими! переменными!) Типа такого:
class dllclass{...};
...
h=LoadLibrary(...);
...
dllclass obj=CreateObjectInProcessMemoryByClassNameWhichDefinedInExternDLL(h,"dllclass"...)
...
Или быть может я многого хочу, может существуют ограничения? Т.Е. если укажу для каждого объекта (как в примере выше) указателями на одни и теже функции описанные в DLL, то меня это не устроит - ведь они должны работать с полями конкретного экземпляра класса! (как до них добраться - это уже второй вопрос)



Ответ на первый вопрос:
для вызова методов-членов в данном случае надо использовать ->* и .*
(Obj.*Demo)("Test");
кстати, не забудь импортировать и вызвать конструктор для соотв. класса аналогичным образом.

Ответ на втророй вопрос:
для получения доступа к переменным класса можно использовать тот же GetProcAddress
int *pVar;
pVar = (int*)GetProcAddress(hLib, "Var");

Это все описано здесь:
http://www.rsdn.ru/article/baseserv/dlluse.xml

P.S. Хотя, я не вижу особого смысла всего этого, помоему проще использовать фабрики.

8.1K
05 октября 2004 года
MegaBrain
7 / / 30.09.2004
Спасибо за грамотную ссылку: я постоянно захожу на RSDN, но я почему-то решил что там будет то же самое, что и везде -> решил спросить на форуме.
1.8K
05 октября 2004 года
_const_
229 / / 26.11.2003
Цитата:
Originally posted by MegaBrain
Мне нужно явно(!) подключить dll c классом, но я не знаю как в таком случае импортировать переменные! классов:
#include <windows.h>
class MyDllClass{
public:
void (*Demo) (char *str);
};
main()
{
HINSTANCE h=LoadLibrary("DllClass.dll");
MyDllClass Obj;
Obj.Demo=(void (*) (char *str))
GetProcAddress(h,"Demo");
//выполняем конструктор
Obj.Demo("Test");
}
Т.е. после демангливания (через Def), как обратиться к переменной объекта класса (для каждого своя!)? Или нужно обязательно создавать
функции типа Get/Set? Вообще нигде! не написано про обращение к переменным dll (импорт из dll) при явной! загрузке (везде - только про функции - GetProcAddress). При неявной загрузке - проблем нет!




Если не ошибаюсь, то в МСДН сказано, что dll может экспортировать только ф-ции и глобальные переменные. Если нужно получить класс, то надо хитрить: в программе объявляется УКАЗАТЕЛЬ на класс, а в dll - ф-ция, которая будет этот класс создавать и возвращать указатель на него. Короче - все как в COM (CreateInstance).

8.1K
14 октября 2004 года
MegaBrain
7 / / 30.09.2004
И все таки я извратился! Меня интересовало то, как будет работать функция с внутренним членом класса если она потеряфет связь с классом при динамической загрузке с def-файлом? А никак! Бех хитростей будет Access Violation! Но т.к. компилятор преобразует методы классов в обычные методы с передачей в них this через стек, то можно замутить вот такое:
// mydll.cpp
#include "stdafx.h"
class __declspec(dllexport) dllclass
{
public:
int j;
void __cdecl Demo(int val);
};
void dllclass::Demo(int val)
{
j=val; //<<Вниание сюда!
}
...
#include "windows.h"
#include "stdafx.h"
#include <afxwin.h>
class _dllclass{
public:
int j;
void (__cdecl *Demo)(_dllclass* ,int);
void _Demo(int Var);
};
void _dllclass::_Demo(int Var)
{
Demo(this,Var);
}


int main(int argc, char* argv[])
{
HINSTANCE h=LoadLibrary("mydll.dll");
_dllclass obj;

obj.Demo=(void (*) (_dllclass* ,int)) GetProcAddress(h,"Demo");

obj._Demo(10);
return 0;
}
...
Вот такие пироги...
1.8K
14 октября 2004 года
_const_
229 / / 26.11.2003
Цитата:
Originally posted by MegaBrain
И все таки я извратился! Меня интересовало то, как будет работать функция с внутренним членом класса если она потеряфет связь с классом при динамической загрузке с def-файлом? А никак! Бех хитростей будет Access Violation! Но т.к. компилятор преобразует методы классов в обычные методы с передачей в них this через стек, то можно замутить вот такое:
// mydll.cpp
#include "stdafx.h"
class __declspec(dllexport) dllclass
{
public:
int j;
void __cdecl Demo(int val);
};
void dllclass::Demo(int val)
{
j=val; //<<Вниание сюда!
}
...
#include "windows.h"
#include "stdafx.h"
#include <afxwin.h>
class _dllclass{
public:
int j;
void (__cdecl *Demo)(_dllclass* ,int);
void _Demo(int Var);
};
void _dllclass::_Demo(int Var)
{
Demo(this,Var);
}


int main(int argc, char* argv[])
{
HINSTANCE h=LoadLibrary("mydll.dll");
_dllclass obj;

obj.Demo=(void (*) (_dllclass* ,int)) GetProcAddress(h,"Demo");

obj._Demo(10);
return 0;
}
...
Вот такие пироги...



Но при таком подходе есть одно НО. Тебе необходимо иметь ДВА описания по сути одного и того же класса: с обычными методами для dll и с указателями на методы - для программы. В СОМ-подходе нужен только ОДИН хедер, который вставляется и в программу, и в dll, что упрощает изменения в коде. Хотя, если подумать, то можно упростить изменения и при 2-х определениях класса.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог