Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.04.2012, 16:08   #1
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию использование классов в dll

итакс...

описал класс TTest в юните TestUnit
вот такого содержания:

Код:
TTest = class 
 FName:string; // в конструкторе присваивается значение "Bugoga"
 constructor Create;  
 procedure Bebe;
end;
...
(реализация класса)
добавляю этот юнит в uses проекта dll:
Код:
library Project1;
uses
SysUtils, Debug, TestUnit;
...
объявляю в библиотеке функцию создания объекта этого класса:

Код:
function CreateTest:TTest;
begin
Result:=TTest.Create;
end;
экспортирую еe:
exports CreateTest;

компилирую...
Все, жизнь удалась! почти...
Дело за малым - воспользоваться этим классом в проге!
ну что тут сложного?...

описываю в проге фантома:
Код:
TBug = class
FName:string;
procedure Bebe; dynamic; (virtual, abstract - чего только не пробовал...) 
end;
функцию для его создания:
CreateBug:function:TBug;

переменную, в которую он будет создан:
Bug:TBug;

загружаю библиотеку и нахожу в ней нужную функцию:
Код:
LibHandle:=LoadLibrary('Project1.dll');
@CreateBug := GetProcAddress(LibHandle,'CreateTCyka');
создаю класс из библиотеки:
Bug:=CreateBug;

... еще немного и я буду на седьмом небе от счастья! ...
итак, все успешно создается!

проверяю FName = "Bugoga" (клево!)
значит все работает!
создался именно нужный класс из библиотеки, о чем говорит значение этой переменной!
а теперь я хочу воспользоваться методом этого класса! ура!
Bug.Bebe;
...
я так понимаю, что люди, которые могут помочь в этом вопросе,
уже догадываются чем закончилась эта история...

остальным намекну: Access Violation bla-bla-bla...
ошибка именно при попытке обратиться к методу объекта...

что я делаю не так?
что нужно сделать чтобы воспользоваться классом, описанным в библиотеке?
xrob вне форума Ответить с цитированием
Старый 12.04.2012, 17:06   #2
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

В самой длл метод класса должен быть виртуальным. И в экзешнике тоже.
EUGY вне форума Ответить с цитированием
Старый 12.04.2012, 17:13   #3
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

сделал все виртуальными...
эффект тот же, нихрена не изменилось =(
xrob вне форума Ответить с цитированием
Старый 12.04.2012, 17:21   #4
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Не рассказывай сказки...
Обязано работать.

ДЛЛ:
Код:
unit Unit1;

interface

implementation

type TTest = class
  FName:string; 
  constructor Create;
  procedure Bebe; virtual;
end;

constructor TTest.Create;
begin
  FName := 'qwerty';
end;

procedure TTest.Bebe;
begin
  FName := 'asdfg';
end;

function CreateTest: TTest ; export;
begin
    Result := TTest.Create;
end;

exports CreateTest;

begin

end.

EXE:

Код:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
     { Private declarations }
  public
    { Public declarations }
  end;

type TBug = class
  FName:string;
  procedure Bebe; virtual;
end;

var
  Form1: TForm1;
  LibHandle: Integer;
  CreateBug:  function: TBug;
  Bug: TBug;


implementation

procedure TBug.Bebe; // заглушка
begin

end;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin

   LibHandle:=LoadLibrary('Project1.dll');
   @CreateBug := GetProcAddress(LibHandle,'CreateTest');
   Bug:=CreateBug;
   Bug.Bebe();  // после вызова меняется значение  FName

end;
end.
На делфи не пишу, но просто из принципа попробывал...
Все работает. Идет вызов метода класса в длл.
EUGY вне форума Ответить с цитированием
Старый 12.04.2012, 17:57   #5
GreenWizard
мальчик-помогай =)
Форумчанин
 
Регистрация: 16.09.2010
Сообщений: 522
По умолчанию

используй интерфейсы или уж функции внутри dll для вызова методов, НО никогда не пытайся напрямую угадать с методами
какой смысл в dll, если ты должен точно воспроизвести класс в программе? 1 поле добавь/удали и уже совсем другие смещения в VMT, а если код библиотеки и проги доступен, то какой смысл переносить класс в dll?
GreenWizard вне форума Ответить с цитированием
Старый 12.04.2012, 18:16   #6
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Цитата:
какой смысл в dll, если ты должен точно воспроизвести класс в программе?
О чем Вы?
Копируется прототип. Реализация методов не нужна.
Пользуясь сишной терминологией, можно сказать и длл и exe должны иметь единый заголовочный файл.
А вот ключевой момент в том, что методы должны быть виртуальными.
EUGY вне форума Ответить с цитированием
Старый 12.04.2012, 18:21   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

эмм, там же много нюансов выходит.
может лучше применить bpl?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 12.04.2012, 18:25   #8
GreenWizard
мальчик-помогай =)
Форумчанин
 
Регистрация: 16.09.2010
Сообщений: 522
По умолчанию

Цитата:
Сообщение от EUGY Посмотреть сообщение
Копируется прототип. Реализация методов не нужна.
и смысл тогда в классах равен -1 т.к. интерфейсы позволяют обьявлять именно такие прототипы классов + имеют механизмы полезные
конечно, если вы просто изучаете программирование, то можно организовать объекты на основе записей, но стоит ли такое делать в реальном проекте? в реальном проекте для ООП есть классы, а для связи класс_в_dll-программа есть интерфейсы
GreenWizard вне форума Ответить с цитированием
Старый 12.04.2012, 18:27   #9
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

оу, GreenWizard, дружище =)
включи воображение!
поскольку и длл и прога мои, то че мне там угадывать?
я и сам все знаю где у меня что...
точно воспроизводить класс не нужно.

попробую объяснить...
вот у тебя есть руки? считай что это прога.
а длл - это то что ты можешь взять в эти руки.
итак, у самого по себе у тебя есть только голые руки,
но если ты возьмешь в эти руки молоток - ты сможешь забивать гвозди,
а если ты возьмешь в эти руки ножик, то ты сможешь резать картошку.
не, ты, конечно, мог бы сразу родиться с ножиком или молотком вместо рук,
но тогда все что ты мог бы делать за свою счастливую жизнь -
это либо забивать гвозди, либо резать картошку =)
(это к слову о зачем переносить класс в длл)

и рукам твоим вобщем то пофиг как ножик режет картошку или как молоток зибивает гвозди.
так же и проге... ей пофиг, что делает класс.
она просто говорит "TTest, я вызываю тебя!", он приходит и делает всю работу.
и все счастливы.

кстати, раз уж пошла такая туса...
VMT - это что?
в контексте нашего разговора я так предполагаю что это типа "таблица соответствия методов", м?
ну и более конкретный вопрос:
когда я вызываю Bug.Bebe, почему вызывается именно метод Bebe из длл?
какая между ними взаимосвязь?
по названию?

p.s.
чувствую себя идиотом, потому что так и не нашел в чем проблема =(
вручную просмотрел всю систему - принципиально все так же как написал EUGY,
методы везде виртуальные...
несколько раз перепроверил, несколько раз перекомпилил длл, прогу...
и все-равно выдавало Acces Violation (((
тогда начал тупо копировать приведенный пример...
в итоге заработало, так что я вам весьма признателен,
но я так и не понял в чем я был не прав...
ваш пример не открыл для меня ничего сверхъестественного,
все что вы написали я знал и раньше и так же точно все делал,
но ваш пример работает, а мой - нет...

Последний раз редактировалось xrob; 12.04.2012 в 18:33.
xrob вне форума Ответить с цитированием
Старый 12.04.2012, 18:36   #10
GreenWizard
мальчик-помогай =)
Форумчанин
 
Регистрация: 16.09.2010
Сообщений: 522
По умолчанию

если знаешь всё о классе, то смысл в dll?))
да, проще и короче делать как ты, но это игры с рандомом))) случайно что-то забыл, в памяти данные иначе расположились и т.п. - crash!
конечно, сам решай, но потом таки придёшь к интерфейсам) я лишь советую их сразу внедрить
удачи с прогой)
GreenWizard вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Использование классов SoftKoc Свободное общение 5 11.02.2011 20:05
С++ использование классов moron Помощь студентам 3 06.04.2010 00:30
С++ использование классов moron Общие вопросы C/C++ 0 03.04.2010 22:40
Создание классов и использование объектов классов при написании программ в среде C++. Frozen inside Помощь студентам 0 16.04.2009 23:18
Использование C++ классов из native DLL в .NET C# lexluther Общие вопросы C/C++ 1 31.01.2007 22:00