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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 26.06.2012, 20:17   #1
soton1989
 
Регистрация: 16.10.2009
Сообщений: 3
По умолчанию Доступ к DLL

Сделал DLL с формой внутри, вызываю ее из основной программы:
Код:
var
  dllHandle:THandle;
  ShowAddPDF: procedure(Handle: THandle)stdcall;
begin
  @ShowAddPDF:=nil;
  dllHandle:=LoadLibrary('workPDF.dll');

  if dllHandle<>0 then
  begin
    @ShowAddPDF:=GetProcAddress(dllHandle,'ShowAddPDF');
    if @ShowAddPDF<>nil then
       ShowAddPDF(Handle);
    FreeLibrary(dllHandle);
  end;


end;
сама dll:
Код:
library workPDF;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  System.SysUtils,
  System.Classes,
  AddPDF in 'AddPDF.pas' {fAddPDF};

{$R *.res}

exports ShowAddPDF index 10;


begin
end.
и код сохраненной в ней формы:
Код:
unit AddPDF;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.ComCtrls,
  Vcl.ToolWin, Vcl.Buttons;

type
  TfAddPDF = class(TForm)
    SectEdit: TEdit;
    SubSectEdit: TEdit;
    TopicEdit: TEdit;
    Раздел: TLabel;
    Подраздел: TLabel;
    Тема: TLabel;
    RichEdit1: TRichEdit;
    Label1: TLabel;
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    Image1: TImage;
    Panel4: TPanel;
    OkBtn: TBitBtn;
    CancelBtn: TBitBtn;
    BitBtn1: TBitBtn;
    ToolBar1: TToolBar;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  fAddPDF: TfAddPDF;
  procedure ShowAddPDF(Handle: THandle);export;stdcall;

implementation

{$R *.dfm}
procedure ShowAddPDF(Handle:THandle);
begin
  Application.Handle:=Handle;
  fAddPDF:=fAddPDF.Create(Application);
  fAddPDF.ShowModal;
end;


end.
при вызове вылетает ошибка:
Access violation ot address 0161130b in module 'workPDF.dll'. Read address 00000000
soton1989 вне форума Ответить с цитированием
Старый 26.06.2012, 20:29   #2
ych_del
Форумчанин
 
Аватар для ych_del
 
Регистрация: 06.02.2011
Сообщений: 149
По умолчанию

А кто будет передавать в DLL такие вещи, как Application и Screen?
При вызове функции это все надо передать, в самой dll-ке указать (не забыв при этом сохранить оригинальные) что-то вроде

Код:
DllApp := Application;
DllScr := Screen;

Application := ПереданныйApplication;
Screen := ПереданныйScreen;
При завершении работы DLL:

Код:
Application := DllApp;
Screeen := DllScr;
А вообще - следовало по шагам пройтись, отслеживая значения всего-всего, и обнаружить, что Application в строке Application.Handle:=Handle; у тебя = nil.
На будущее (в простом изложении):

Сообщение об ошибке Read address 00000000 явно указывает на то, что ты обращаешься к несозданному объекту.
Профессиональный конвертор галлюцинаций заказчика в алгоритмическую структуру.

Последний раз редактировалось ych_del; 26.06.2012 в 20:34.
ych_del вне форума Ответить с цитированием
Старый 26.06.2012, 21:36   #3
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Цитата:
А кто будет передавать в DLL такие вещи, как Application и Screen?
Жеесть.

Цитата:
А вообще - следовало по шагам пройтись, отслеживая значения всего-всего, и обнаружить, что Application в строке Application.Handle:=Handle; у тебя = nil.
Ты врёшь.

Цитата:
при вызове вылетает ошибка:
Access violation ot address 0161130b in module 'workPDF.dll'. Read address 00000000
Есть мнение, что если запускать проект DLL под отладчиком, то при этом сообщении отладчик тебя носом тыркнет в строчку с ошибкой.

Если не получается, то вот список, который надо проверить:
1. Подчисти и изолируй код:

Код:
procedure ShowAddPDF(Handle: THandle); stdcall;
var
  AddPDF: TfAddPDF; // убери это объявление из interface модуля
begin
  Application.Handle := Handle;
  try
    AddPDF := TAddPDF.Create(nil);
    try 
      AddPDF.ShowModal;
    finally
      FreeAndNil(AddPDF);
    end;
  finally
    Application.Handle := 0;
  end;
end;
2. Попробуй тот же проект, но с пустой формой.
3. Проверь форму отдельно в exe проекте.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 27.06.2012, 09:41   #4
soton1989
 
Регистрация: 16.10.2009
Сообщений: 3
По умолчанию

Огромное спасибо, на первом пункте все заработало
soton1989 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Загрузка Dll и доступ CallNextHookEx к памяти Smogg Win Api 1 24.02.2012 17:16
Доступ к переменной, объявленной в одной dll, из другой dll eduard93 Visual C++ 2 25.09.2011 11:10
Ошибка при выхове функций Bass.dll из другой DLL SalasAndriy Общие вопросы Delphi 7 21.10.2009 23:36
доступ к значениям предыдущей сессии в DLL Kat Hilario Общие вопросы C/C++ 4 12.03.2009 12:13