Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> передача фннкции из объекта 
:(
    Опции темы
z-END
Дата 21.12.2005, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 11
Всего: 102



есть объект надо передать его функцию в подгружаемую dll
Код
Type TSimpleObject=Object
       private
         function TheSomeFunc (Param1:Word; Param2:PAnsiChar):PAnsiChar;
         _open:procedure (SomeFunc:Pointer);
         {...}
       public
         {...}
        procedure Init;
       end;  
{...}
TSimpleObject.Init;
begin
try
  hW := LoadLibrary (PAnsiChar (PluginName));
  @_open := GetProcAddress (hW, 'open_DLL');
  @_close := GetProcAddress (hW, 'close_DLL');
  _open (@TheSomeFunc); // <-- вот здесь ошибка Variable type required
except  Failed := True; end;
end;

хотя если вынести данный код (TheSomeFunc) из тела объекта и поместить в качестве отдельной функции то все работает, но нужно именно из объекта... как быть?


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Snowy
Дата 21.12.2005, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Попробуй создать тип
Код

  TSomeStrange = function (Param1:Word; Param2:PAnsiChar):PAnsiChar of object;

  TSimpleObject=Object
   private
     function TheSomeFunc (Param1:Word; Param2:PAnsiChar):PAnsiChar;
   public
     _open: procedure (SomeFunc:Pointer);
     _close: procedure (SomeFunc:Pointer);
     some:  TSomeStrange;
   procedure Init;
 end;

 // .....

  hW := LoadLibrary (PAnsiChar (PluginName));
  @_open := GetProcAddress (hW, 'open_DLL');
  @_close := GetProcAddress (hW, 'close_DLL');
  some:=TheSomeFunc;
  _open(Addr(some)); // <-- вот здесь ошибка Variable type required не вылетает


PM MAIL   Вверх
z-END
Дата 21.12.2005, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 11
Всего: 102



так работает... но несовсем так как надоsmile
в dll использую такую конструкцию:
Код

type TsomeFunc=function (Param1:Word; Param2:PAnsiChar):PAnsiChar;
var somFunc:TSomeFunc;
{..}
procedure _open (pFunc: Pointer);
begin
@someFunc := pFunc;
someFunc (1,nil);
end;


в объекте такой код:
Код

function TsimpleObject.TheSomeFunc;
begin
{ля-ля-ля}
end;

причем код {ля-ля-ля} выполняется, но если в нем использовать такой вариант:
Код

function TsimpleObject.TheSomeFunc;
begin
Name:='test'; // Name - переменная объекта
{ля-ля-ля}
end;

то вываливается сообщение об ошибке AV. а я как раз и пытался переместить тело функции в объект чтобы работать с его переменными. получается что так нельзя? или я неправильно что-то деалю?


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Snowy
Дата 21.12.2005, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Это же dll. Конечно нельзя.
Вместо прямого доступа к полям, ты должен передать указатель на структуру, которую функция заполнит и вернет тебе.
А ты уже раскладывай по нужным тебе полям.
PM MAIL   Вверх
z-END
Дата 21.12.2005, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 11
Всего: 102



Цитата(Snowy @ 21.12.2005, 13:53)
Вместо прямого доступа к полям, ты должен передать указатель на структуру, которую функция заполнит и вернет тебе.

дык из длл я и не использую прямой доступ к полям объекта, из длл я выполняю функцию которая является частью объекта, и уже она в свою очередь использует доступ к полям...
или я душа заблудшая?


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Snowy
Дата 21.12.2005, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Цитата(z @ 21.12.2005, 14:14)
из длл я выполняю функцию которая является частью объекта, и уже она в свою очередь использует доступ к полям...

Нет, из dll ты не можешь использовать доступ к полям, даже вызывая этот метод.
Для dll это обычная функция, а не функция класса.
Как вариант, ты можешь использовать левую функцию и передавать ей указатель на объект.
При возврате в exe, именуешь указатель объектом и вызываешь метод.
PM MAIL   Вверх
z-END
Дата 21.12.2005, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 11
Всего: 102



Цитата(Snowy @ 21.12.2005, 14:49)
Как вариант, ты можешь использовать левую функцию и передавать ей указатель на объект.
При возврате в exe, именуешь указатель объектом и вызываешь метод.

приблизительно так и делал.. уж больно массивно показалось решил упростить... ну лан придется обратно откатываться smile


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Snowy
Дата 21.12.2005, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Код

  TSimpleObject=class
   private
     Name: string;
     function TheSomeFunc(Param1:Word; Param2:PAnsiChar):PAnsiChar;
   public
     _open: procedure (obj, SomeFunc:Pointer);
     _close: procedure (obj, SomeFunc:Pointer);
   procedure Init;
 end;

implementation

function some(obj: pointer; Param1:Word; Param2:PAnsiChar):PAnsiChar;
begin
  if obj<>nil
    then result:=TSimpleObject(obj).TheSomeFunc(Param1, Param2)
  else result:=nil;
end;

procedure TSimpleObject.Init;
var
  hW: HMODULE;
  PluginName: string;
begin
  hW := LoadLibrary (PAnsiChar (PluginName));
  @_open := GetProcAddress (hW, 'open_DLL');
  @_close := GetProcAddress (hW, 'close_DLL');
  _open(pointer(self), Addr(some));
end;

function TSimpleObject.TheSomeFunc;
begin
  Name:=Param2;
  result:=Param2;
end;

Только в таком случае нужно делать не объект, а класс.
Добавлено @ 15:02
Код

type TsomeFunc=function (obj: pointer; Param1:Word; Param2:PAnsiChar):PAnsiChar;    

var somFunc:TSomeFunc;

procedure _open (obj, pFunc: Pointer);    
begin    
  @someFunc := pFunc;    
  someFunc (obj, 1,nil);
end;

PM MAIL   Вверх
Snowy
Дата 21.12.2005, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Кратко объясню суть проблемы.
Реально, т.к. функция function TheSomeFunc(Param1:Word; Param2:PAnsiChar):PAnsiChar является методом, то у нее не 2 параметра а 3.
Третий параметр - Self, указывающий на экземпляр.
Т.к. ты вызываешь ее из dll, то она не получает этого Self и не может обратиться к полям экземпляра.
Поэтому для корректной работы нужно дать ей этот параметр.
Внедряться в модель дельфи неразумно.
Поэтому лучше сделать третью функцию, которая будет явно получать указатель на этот экземпляр и вызывать метод так, как полагается.
PM MAIL   Вверх
Демо
Дата 21.12.2005, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 30
Всего: 50



> Автор
Для подобных манипуляций есть простой прием:

Создается промежуточная функция в основной программе, которая получает экземпляр объекта.
В этой функции уже вызывается метод и функция из DLL.


--------------------
    
PM MAIL ICQ Skype   Вверх
z-END
Дата 21.12.2005, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 11
Всего: 102



Цитата(Snowy @ 21.12.2005, 14:58)
function some(obj: pointer; Param1:Word; Param2:PAnsiChar):PAnsiChar;
begin
  if obj<>nil
    then result:=TSimpleObject(obj).TheSomeFunc(Param1, Param2)
  else result:=nil;
end;

почему-то в этом месте obj всегда nil, хотя при вызове таковым не является smile
Добавлено @ 16:13
Цитата
Создается промежуточная функция в основной программе, которая получает экземпляр объекта.
В этой функции уже вызывается метод и функция из DLL.

этого мне категорически ненадо, доступа из длл к объекту быть недолжно, т.е. в длл даже неизвестна его структура...


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Snowy
Дата 21.12.2005, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Цитата(z @ 21.12.2005, 16:08)
почему-то в этом месте obj всегда nil, хотя при вызове таковым не является

Проверь, чему равняется obj в других функциях: Init и _open.
PM MAIL   Вверх
z-END
Дата 21.12.2005, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 11
Всего: 102



Все разобрался! Snowy спасибо! за разъяснения


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1324 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.