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

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

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

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 02.09.2013, 14:03   #1
moon-guest
Пользователь
 
Аватар для moon-guest
 
Регистрация: 14.11.2010
Сообщений: 27
По умолчанию Статическая и динамическая загрузка класса из библиотеки

Всем здрасте)))

Возникла потребность реализации набора библиотек с одинаковым интерфейсом но разным родам работы.
Для этих целей бал реализован интерфейс по нему был создан класс и был внесён в библиотеку.

Код:
type
 IMyInterface = Interface(IUnknown)
    ['{48673D2F-F3B1-47F1-97E7-A3D1D8837A07}']
    function GetNameProtocol: PChar;
    function GetVersionProtocol: Integer;
    .....
    property NameProtocol: PChar read GetNameProtocol;
    property VersionProtocol: Integer read GetVersionProtocol;
    .....
  end;

TMyClass = class(TInterfacedObject, MyInterface)
  private
    function GetNameProtocol: PChar;
    function GetVersionProtocol: Integer;
  public
    constructor Create;
    property NameProtocol: PChar read GetNameProtocol;
    property VersionProtocol: Integer read GetVersionProtocol;
  end;
Функция объявления класса из библиотеки:

Код:
function MyInterfaceClass: IMyInterface; stdcall;
begin
  Result := TMyClass.Create;
end;
На стороне программы для идентификации используется выше упомянутый интерфейс.
В ходе выполнения программы при статической загрузке класса из библиотеки

Код:
type
   function MyInterfaceClass: IMyInterface; stdcall; external 'mydll.dll';
var
   nObj: IMyInterface;
....
   nObj:= MyInterfaceClass;
   caption:=nObj.NameProtocol;
все протекает стабильно, но при переводе программы на динамический режим работы

Код:
var
   LibHandle: Integer;
   Init: function: IMyInterface; stdcall;
.....
   LibHandle:=LoadLibrary(PChar('mydll.dll'));
  @Init := GetProcAddress(LibHandle, 'MyInterfaceClass');
  showmessage(Init.NameProtocol);
  FreeLibrary(LibHandle);
она выдает ошибку:

Код:
 Project Project1.exe raised exception class EAccessViolation with message
 'Access violation at address 0040545A in module'Project1.exe'. Raise of address 010C07F8'. 
Process stopped. Use Step or Run tocontinue.
moon-guest вне форума Ответить с цитированием
Старый 02.09.2013, 17:34   #2
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

Код:
function MyInterfaceClass: IMyInterface; stdcall;
begin
  Result := TMyClass.Create as IMyInterface;
end;
property NameProtocol: PChar read GetNameProtocol; - плохой вариант
возможна ссылка на константу в dll и при выгрузке она засрется...
Не стесняемся, плюсуем!

Последний раз редактировалось Slym; 02.09.2013 в 20:02.
Slym вне форума Ответить с цитированием
Старый 03.09.2013, 00:40   #3
spamer
Software Developer
Старожил
 
Аватар для spamer
 
Регистрация: 19.12.2008
Сообщений: 2,070
По умолчанию

В Delphi для передачи строк из/в dll стоит использовать тип WideString: подробнее тут.
Будь проще и люди к тебе потянутся
spamer вне форума Ответить с цитированием
Старый 03.09.2013, 05:18   #4
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,755
По умолчанию

Цитата:
Сообщение от moon-guest Посмотреть сообщение
Код:
  FreeLibrary(LibHandle);
Вот это круто, вот это я понимаю! Получил интерфейс из библиотеки, -- всё, библиотека больше не нужна, выгружаем. Дальше все по волшебству работать будет. Ан нет...
Vapaamies вне форума Ответить с цитированием
Старый 03.09.2013, 12:43   #5
moon-guest
Пользователь
 
Аватар для moon-guest
 
Регистрация: 14.11.2010
Сообщений: 27
По умолчанию

Решение нашлось добавлением "as IMyInterface" и использование "FreeLibrary(LibHandle)" только после проверки на присутствие загруженной библиотеки. Но это не решало проблему с внесением данных в переменные класса. Решение нашлось после присвоения загруженной функции переменной типа интерфейса.

В библиотеке
Код:
type
   IMyInterface = Interface(IUnknown)
    ['{48673D2F-F3B1-47F1-97E7-A3D1D8837A07}']
    ......
    procedure SetData(value: variant);
    property Data: variant write SetData;
  end;

  TMyClass = class(TInterfacedObject, MyInterface)
  private
    FData: Variant;
    ......
    procedure SetData(value: variant);
  public
    ......
    property Data: variant read FData write SetData;
  end;
В исполняемом файле

Код:
var
   nObj: IMyInterface;
.....
  if LibHandle >= 0 then FreeLibrary(LibHandle);
  LibHandle:=LoadLibrary(PChar('mydll.dll'));
  @Init := GetProcAddress(LibHandle, 'MyInterfaceClass');
  nObj:=Init;
  nObj.Data:='Big World!';
  showmessage(nObj.Data);
Решение нашлось в DelphiWorld при реализации модели объектных компонентов.
moon-guest вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Динамическая загрузка контента SweetOpium PHP 8 31.07.2013 16:40
Статическая функция класса в С++ Артём Волжанкин Помощь студентам 12 03.05.2013 18:42
Динамическая загрузка dll Dizelektwo Win Api 8 20.06.2012 16:56
Динамическая загрузка формы из DLL grominfo Помощь студентам 1 15.11.2011 17:10
Динамическая загрузка DLL ImportDLL Общие вопросы C/C++ 2 12.06.2009 11:33