Конференция "Основная" » Проблема при работе с DLL
 
  • 0x01 (12.03.08 15:12) [0]
    Собственно проблема заключается в том, что при работе программы с DLL возникает ошибка при закрытии программы(Invalid pointer operation).

    В программе выполняются 2 процедуры:
    1. Вызывается функция из DLL
    2. Помещается на форму изображение которое расположенно в DLL

    Выкладываю код:

    unit Unit1;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes,
      Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;

    type
      TForm1 = class(TForm)
        Button1: TButton;
       Button2: TButton;
       Image1: TImage;
        procedure Button1Click(Sender: TObject) ;
       procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;

    var
      Form1: TForm1;
     procedure DllMessage; external 'test1.dll'; //вызывается функция

    implementation

    {$R *.dfm}
    procedure TForm1.Button1Click(Sender: TObject) ;
    begin
     try
      DllMessage;
     finally
      //application.Terminate;
     end;
     // showmessage('test1.dll');
    end;

    procedure TForm1.Button2Click(Sender: TObject);// распологает BMP // на форме
     const
     resGIF = 'progress';
    var
     h : THandle;
     gif : TImage;
     r:TRect;

    begin
    h := LoadLibrary('dll1.dll');
     try
       if h <> 0 then
       begin
    gif := Image1;//.Create(Image1);
       try
    gif.Picture.Bitmap.LoadFromResourceName(h,resGIF);
    ShowMessage('Load Resource DLL !');
    finally
    gif.Picture.Free;
    end;

    end
       else
       begin
         ShowMessage('Load Resource DLL FAILED!');
       end;
     finally
       FreeLibrary(h);
     end;
    end;
    end.



    Где допущена ошибка?
    Заранее спасибо!
  • Reindeer Moss Eater © (12.03.08 15:47) [1]
    например может быть нарушено соглашение о вызовах и как следствие испорченный стек и ошибка.
  • Eraser © (12.03.08 15:48) [2]

    > 0x01   (12.03.08 15:12) 


    >  procedure DllMessage; external 'test1.dll';

    говорит о том, что DLL будет загружаться в память при запуске приложения, так что убери Load/FreeLibrary.
  • Reindeer Moss Eater © (12.03.08 15:52) [3]
    У него лоад для другой длл делается
  • 0x01 (12.03.08 16:45) [4]
    Возможно будет проще создать процедуру которая располагает заданное изображение или иконку на форме. Как при таком алгоритме будут загружаться и выгружаться DLL? Рационален ли такой подход и можно ли так избежать ошибок?
  • Reindeer Moss Eater © (12.03.08 16:52) [5]
    Будет намного лучше, если не философствовать многозначительно, а банально проверять результат, возвращаемый функциями и смотреть значение гетластеррор.
  • 0x01 (12.03.08 16:57) [6]
    First chance exception at $7C812A7B. Exception class EInvalidPointer with message 'Invalid pointer operation'. Process test.exe (5608)
  • Reindeer Moss Eater © (12.03.08 16:59) [7]
    соглашения о вызовах соблюдены?
  • 0x01 (12.03.08 16:59) [8]
    Эта ошибка возникает при закрытии программы. А работа с DLL протекает без ошибок
  • Reindeer Moss Eater © (12.03.08 17:01) [9]
    Мужик, соглашения о вызовах соблюдены у тебя или нет?
  • 0x01 (12.03.08 17:08) [10]
    Из кода видно, что  первая DLL ('test1.dll') загружается при старте программы- статически, а вторая по требованию- т.е при нажатии кнопки- динамически. Какие соглашения о вызовах могут быть не соблюдены? Соглашения о вызовах - как я понял это декларация (объявление) способа загрузки DLL. Это так?
  • Германн © (12.03.08 17:25) [11]

    > 0x01   (12.03.08 17:08) [10]

    Читать в справке про calling convention
  • MetalFan © (12.03.08 17:27) [12]

    > gif := Image1;//.Create(Image1);
    >...
    > gif.Picture.Free;
    > ...

    хм. как-то нехорошо получается.
  • 0x01 (12.03.08 17:49) [13]

    > Германн ©   (12.03.08 17:25) [11]


    Спасибо!

    А в данной ситуации что нужно подправить в коде?


    > MetalFan ©   (12.03.08 17:27) [12]

    Почему?
  • MetalFan © (12.03.08 19:04) [14]
    ну ты взял у Image1 объектное св-во убил...
    хотя надо глянуть vcl, может оно там обрабатывается верно...
  • MetalFan © (12.03.08 19:07) [15]
    нет, на сколько я понял TImage знать не узнает, что ты его Picture грохнул
  • 0x01 (12.03.08 19:38) [16]
    Кто нибудь может написать пример кода, где при нажатии на кнопку создается TImage-> получается BMP/JPG из DLL  -> устанавливается полученное изображение на форму?
  • Германн © (13.03.08 01:09) [17]

    > 0x01   (12.03.08 19:38) [16]
    >
    > Кто нибудь может написать пример кода, где при нажатии на
    > кнопку создается TImage-> получается BMP/JPG из DLL  ->
    > устанавливается полученное изображение на форму?
    >

    "Кто-нибудь" может, но лень. И ты сможешь, возможно, если по примеру MetalFan © глянешь в генофонд.

    P.S. Насколько понял, DLL тут вообще ни при чем.
  • MetalFan © (13.03.08 12:34) [18]

    > при нажатии на кнопку создается TImage

    а зачем динамически создавать TImage? просто на форму положить его нельзя?
  • 0x01 (13.03.08 16:00) [19]

    > MetalFan ©   (13.03.08 12:34) [18]

    Хорошая идея. Тогда получается надо при загрузке приложения статически загрузить нужную DLL и расположить на форме нужную картинку. Правильно понял?
    Только на форму надо ложить изображение которое расположено в DLL, а не в одной папке с EXE приложением.


    > Германн ©   (13.03.08 01:09) [17]


    > P.S. Насколько понял, DLL тут вообще ни при чем.

    А в чем же?
    По предыдущим постам понял что проблема в соглашених о вызовах.
    Разве обязательно при статической загрузки DLL -> 1. объявлять ее в uses
    2. И создавать что-то наподобие

    TResource = class
       class function GetIcon(const DLLName : string; const IconResName : string): HIcon;
       class function GetGIF(const DLLName : string; const GifResName : string): TGifImage;

 
Конференция "Основная" » Проблема при работе с DLL
Есть новые Нет новых   [134483   +44][b:0][p:0.002]