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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамическое связывание DLL и параметры 
V
    Опции темы
Cinemaizer[Олег]
Дата 30.8.2011, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 10.4.2008
Где: Москва

Репутация: нет
Всего: 0



Подскажите плиз как правильно задавать параметры (в моем случае) при неявной загрузке дельфийской dll, поскольку ошибка "Access violation at address 003746DB in module 'gensmart32.dll'. Read of address 00000008" как бы намекает именно на проблемы с этим делом вроде.  smile. Или я неправ?

Суть задачи в следующем: 
По нажатию на DBimage пытаюсь загрузить картинку, которая должна быть уменьшена и вставлена в базу.
Код

type
  TMakeThumbNail = procedure(var src, dest: TBitmap; const ThumbSize: Word); stdcall;
.........................................................
var
  frmSETTINGS: TfrmSETTINGS;
  DLLLibrary: HMODULE;
  MakeThumbNail: TMakeThumbNail;
.........................................................
procedure TfrmSETTINGS.dbimgPHOTOClick(Sender: TObject);
var
  j: TJPEGImage;
  t, d: TBitmap;
begin
  if sOpenPictureDialog1.Execute then
  begin
    j:=TJPEGImage.Create;
    t:=TBitmap.Create;
    try
      j.LoadFromFile(sOpenPictureDialog1.FileName);
      j.Grayscale:=False;
      t.Assign(TGraphic(j));
      d:=TBitmap.Create;

      DLLLibrary:=LoadLibrary('gensmart32.dll');
      @MakeThumbNail:=GetProcAddress(DLLLibrary, 'MakeThumbNail');
      MakeThumbNail(t, d, 161);
      @MakeThumbNail:=nil;
      FreeLibrary(DLLLibrary);

      with DM.dsetFIRMA_DANNYE do
      begin
        Edit;
        dbimgPHOTO.Picture.Bitmap.Assign(d);
        Post;
      end;
    finally
      j.Free;
      t.Free;
      d.Free;
    end;
  end;
end;



Код dll-ки такой:
Код

library gensmart32;

uses
   Windows, SysUtils, Classes, Graphics, System;

{$R *.res}


////////////////////////////////////////////////////////////////////////////////
// Создание тамбнейла
////////////////////////////////////////////////////////////////////////////////
procedure MakeThumbNail(src, dest: TBitmap; ThumbSize: Word); stdcall;
type
  PRGB24 = ^TRGB24;
  TRGB24 = packed record
    B: Byte;
    G: Byte;
    R: Byte;
  end;
var
  x, y, ix, iy: integer;
  x1, x2, x3: integer;

  xscale, yscale: single;
  iRed, iGrn, iBlu, iRatio: Longword;
  p, c1, c2, c3, c4, c5: tRGB24;
  pt, pt1: pRGB24;
  iSrc, iDst, s1: integer;
  i, j, r, g, b, tmpY: integer;

  RowDest, RowSource, RowSourceStart: integer;
  w, h: integer;
  dxmin, dymin: integer;
  ny1, ny2, ny3: integer;
  dx, dy: integer;
  lutX, lutY: array of integer;

begin
  if src.PixelFormat <> pf24bit then src.PixelFormat := pf24bit;
  if dest.PixelFormat <> pf24bit then dest.PixelFormat := pf24bit;
  dest.Width := ThumbSize;
  dest.Height := ThumbSize;
  w := ThumbSize;
  h := ThumbSize;

  if (src.Width <= ThumbSize) and (src.Height <= ThumbSize) then
  begin
    dest.Assign(src);
    exit;
  end;

  iDst := (w * 24 + 31) and not 31;
  iDst := iDst div 8; //BytesPerScanline
  iSrc := (Src.Width * 24 + 31) and not 31;
  iSrc := iSrc div 8;

  xscale := 1 / (w / src.Width);
  yscale := 1 / (h / src.Height);

  // X lookup table
  SetLength(lutX, w);
  x1 := 0;
  x2 := trunc(xscale);
  for x := 0 to w - 1 do
  begin
    lutX[x] := x2 - x1;
    x1 := x2;
    x2 := trunc((x + 2) * xscale);
  end;

  // Y lookup table
  SetLength(lutY, h);
  x1 := 0;
  x2 := trunc(yscale);
  for x := 0 to h - 1 do
  begin
    lutY[x] := x2 - x1;
    x1 := x2;
    x2 := trunc((x + 2) * yscale);
  end;

  dec(w);
  dec(h);
  RowDest := integer(Dest.Scanline[0]);
  RowSourceStart := integer(Src.Scanline[0]);
  RowSource := RowSourceStart;
  for y := 0 to h do
  begin
    dy := lutY[y];
    x1 := 0;
    x3 := 0;
    for x := 0 to w do
    begin
      dx := lutX[x];
      iRed := 0;
      iGrn := 0;
      iBlu := 0;
      RowSource := RowSourceStart;
      for iy := 1 to dy do
      begin
        pt := PRGB24(RowSource + x1);
        for ix := 1 to dx do
        begin
          iRed := iRed + pt.R;
          iGrn := iGrn + pt.G;
          iBlu := iBlu + pt.B;
          inc(pt);
        end;
        RowSource := RowSource - iSrc;
      end;
      iRatio := 65535 div (dx * dy);
      pt1 := PRGB24(RowDest + x3);
      pt1.R := (iRed * iRatio) shr 16;
      pt1.G := (iGrn * iRatio) shr 16;
      pt1.B := (iBlu * iRatio) shr 16;
      x1 := x1 + 3 * dx;
      inc(x3, 3);
    end;
    RowDest := RowDest - iDst;
    RowSourceStart := RowSource;
  end;

  if dest.Height < 3 then exit;

  // Sharpening...
  s1 := integer(dest.ScanLine[0]);
  iDst := integer(dest.ScanLine[1]) - s1;
  ny1 := Integer(s1);
  ny2 := ny1 + iDst;
  ny3 := ny2 + iDst;
  for y := 1 to dest.Height - 2 do
  begin
    for x := 0 to dest.Width - 3 do
    begin
      x1 := x * 3;
      x2 := x1 + 3;
      x3 := x1 + 6;

      c1 := pRGB24(ny1 + x1)^;
      c2 := pRGB24(ny1 + x3)^;
      c3 := pRGB24(ny2 + x2)^;
      c4 := pRGB24(ny3 + x1)^;
      c5 := pRGB24(ny3 + x3)^;

      r := (c1.R + c2.R + (c3.R * -12) + c4.R + c5.R) div -8;
      g := (c1.G + c2.G + (c3.G * -12) + c4.G + c5.G) div -8;
      b := (c1.B + c2.B + (c3.B * -12) + c4.B + c5.B) div -8;

      if r < 0 then r := 0 else if r > 255 then r := 255;
      if g < 0 then g := 0 else if g > 255 then g := 255;
      if b < 0 then b := 0 else if b > 255 then b := 255;

      pt1 := pRGB24(ny2 + x2);
      pt1.R := r;
      pt1.G := g;
      pt1.B := b;
    end;
    inc(ny1, iDst);
    inc(ny2, iDst);
    inc(ny3, iDst);
  end;
end;
.........................................................
exports MakeThumbNail;



В случае, если процедуру MakeThumbNail тупо вставить в модуль(где вышеупомянутая кнопка-dbimage) и отказаться от использования dll, то все работает отлично, а так - спотыкается именно на строке MakeThumbNail(t, d, 161) при нажатии :(

Это сообщение отредактировал(а) Cinemaizer[Олег] - 30.8.2011, 17:55
PM MAIL WWW   Вверх
Frees
Дата 30.8.2011, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 9
Всего: 54



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


--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
RomanEEP
Дата 1.9.2011, 10:40 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 424
Регистрация: 18.5.2006
Где: Коломна

Репутация: 5
Всего: 8



в DLL библиотеку нельзя передавать классы.
procedure(var src, dest: TBitmap; const ThumbSize: Word); stdcall; - недопустимо
PM MAIL   Вверх
rodnover
Дата 1.9.2011, 11:00 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 7.4.2009

Репутация: нет
Всего: 10



При создании dll на Delphi сверху написано такое:

Цитата

{ 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. }


Не в этом проблема?



Цитата(RomanEEP @  1.9.2011,  14:40 Найти цитируемый пост)
в DLL библиотеку нельзя передавать классы.

Я у себя передаю, почему-то всё работает. ;) Главное, чтобы в dll и основной программе классы одинаковых версий использовались.

Это сообщение отредактировал(а) rodnover - 1.9.2011, 11:01
PM MAIL   Вверх
bems
Дата 2.9.2011, 02:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 31
Всего: 88



Цитата(rodnover @  1.9.2011,  11:00 Найти цитируемый пост)
Главное, чтобы в dll и основной программе классы одинаковых версий использовались.
этого мало, а работает потому что везёт. Или скорее не везёт. Как минимум к требованию версий классов нужно добавить требование неиспользования глобальных данных модуля (а для чужих классов это может быть и неизвестно). И даже так не будут работать операторы is и as, и всё что на них завязано (и если для своего кода ты можешь обойтись без них для тех объектов которые у тебя путешествуют между модулями, то с кодом самих этих классов ничего подобного не сделать).
Короче действительно нельзя, правильное решение тут это интерфейсы или bpl


Это сообщение отредактировал(а) bems - 2.9.2011, 03:00


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Akella
Дата 2.9.2011, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


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

Репутация: 36
Всего: 329



Не по теме. А зачем такие сложности для создания эскизов (thumbnails)?
PM MAIL   Вверх
Cinemaizer[Олег]
Дата 2.9.2011, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 10.4.2008
Где: Москва

Репутация: нет
Всего: 0



Цитата(Akella @ 2.9.2011,  10:47)
Не по теме. А зачем такие сложности для создания эскизов (thumbnails)?

Эмм... А затем чтоб не грузить "очень бааальшие" картинки в базе за ненадобностью. Мне в итоге нужно лишь мелкая картинка для печати на бланке.

Это сообщение отредактировал(а) Cinemaizer[Олег] - 2.9.2011, 12:57
PM MAIL WWW   Вверх
Akella
Дата 2.9.2011, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


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

Репутация: 36
Всего: 329



Вопрос ты не понял мой, юный падаван.
PM MAIL   Вверх
Cinemaizer[Олег]
Дата 2.9.2011, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 10.4.2008
Где: Москва

Репутация: нет
Всего: 0



Цитата(Akella @ 2.9.2011,  10:58)
Вопрос ты не понял мой, юный падаван.

Корректнее вопроса своего формулировку формулируйте о, йода-мастер...

В принципе, процесс ужатия больших картинок можно упростить, просто на глаза код попался этот... не удержался от применения )

Это сообщение отредактировал(а) Cinemaizer[Олег] - 2.9.2011, 13:14
PM MAIL WWW   Вверх
Akella
Дата 2.9.2011, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


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

Репутация: 36
Всего: 329



Внимательно прочитай ещё раз smile , вдумчиво. Если не понимаешь, то прочитай ещё раз.

Добавлено через 1 минуту и 20 секунд
Ладно, дам тебе подсказку.
Вот вопрос: А зачет ты делаешь эскизы?

Можешь теперь сравнить. Будем надеяться, что поймёшь ты мой первый вопрос, юный падаван smile

Добавлено через 2 минуты и 7 секунд
Мне кажется, что этот код проще:
Код

procedure JpegToBmp(jpg: TJPEGImage; bmpDest: TBitmap);
var
  tmp: TBitmap;
  ratio: double;
  newW, newH: integer;
begin
  tmp := TBitmap.Create;

  try
//    jpg.Scale := jsEighth;
//    jpg.DIBNeeded;

    tmp.Assign(jpg);

    //если размеры исходного изображеия больше эскиза, то уменьшаем исходное изображением до размеров экскиза
    if (jpg.Width > iThumbnailMaxWidth) and (jpg.Height > iThumbnailMaxHeight) then
    begin

      if tmp.Width > tmp.Height then
        ratio := iThumbnailMaxWidth / tmp.Height
      else
        ratio := iThumbnailMaxHeight / tmp.Height;

      bmpDest.Width  := Round(ratio * tmp.Width);
      bmpDest.Height := Round(ratio * tmp.Height);
    end;//if (jpg.Width > tmp.Width) and (jpg.Height > tmp.Height) then

    SetStretchBltMode(bmpDest.Canvas.Handle, HALFTONE);
    StretchBlt(bmpDest.Canvas.Handle, 0, 0, bmpDest.Width, bmpDest.Height, tmp.Canvas.Handle, 0, 0, tmp.Width, tmp.Height, SRCCOPY);
  finally
    tmp.Free;
  end;
end;


Вопрос лишь в понимании кода и в производительности.
PM MAIL   Вверх
Cinemaizer[Олег]
Дата 2.9.2011, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 10.4.2008
Где: Москва

Репутация: нет
Всего: 0



Цитата(Akella @ 2.9.2011,  11:27)
Внимательно прочитай ещё раз smile , вдумчиво. Если не понимаешь, то прочитай ещё раз.

Добавлено @ 13:28
Ладно, дам тебе подсказку.
Вот вопрос: А зачет ты делаешь эскизы?

Можешь теперь сравнить. Будем надеяться, что поймёшь ты мой первый вопрос, юный падаван smile

Добавлено @ 13:29
Мне кажется, что этот код проще:
Код

procedure JpegToBmp(jpg: TJPEGImage; bmpDest: TBitmap);
var
  tmp: TBitmap;
  ratio: double;
  newW, newH: integer;
begin
  tmp := TBitmap.Create;

  try
//    jpg.Scale := jsEighth;
//    jpg.DIBNeeded;

    tmp.Assign(jpg);

    //если размеры исходного изображеия больше эскиза, то уменьшаем исходное изображением до размеров экскиза
    if (jpg.Width > iThumbnailMaxWidth) and (jpg.Height > iThumbnailMaxHeight) then
    begin

      if tmp.Width > tmp.Height then
        ratio := iThumbnailMaxWidth / tmp.Height
      else
        ratio := iThumbnailMaxHeight / tmp.Height;

      bmpDest.Width  := Round(ratio * tmp.Width);
      bmpDest.Height := Round(ratio * tmp.Height);
    end;//if (jpg.Width > tmp.Width) and (jpg.Height > tmp.Height) then

    SetStretchBltMode(bmpDest.Canvas.Handle, HALFTONE);
    StretchBlt(bmpDest.Canvas.Handle, 0, 0, bmpDest.Width, bmpDest.Height, tmp.Canvas.Handle, 0, 0, tmp.Width, tmp.Height, SRCCOPY);
  finally
    tmp.Free;
  end;
end;


Вопрос лишь в понимании кода и в производительности.

О Уважаемый, йода-мастер!..

Я уже говорил - эскизы делаю именно затем, чтобы не хранить в БД большие картинки (бо - незачем занимать много места), мне они (картинки) нужны в мини-варианте. 
Эскиз который имеется в самом джипеге (а как быть не с джипегами тогда?smile) выцедить было можно бы, наверное... или вот так сделать:
http://otvet.mail.ru/question/37220832/
но вот почему то пошел вышупомянутым путем smile

Добавлено @ 13:43
Уф, незаметил как Акелла добавил код, безусловно это будет и проще и лучше - так и сделаю. Спасибо! smile Однако вопрос с параметрами при динамической связке прояснен до конца? В смысле, можно или нельзя все таки в параметрах использовать классы? Просто это тоже как бы важно.

Это сообщение отредактировал(а) Cinemaizer[Олег] - 2.9.2011, 13:52
PM MAIL WWW   Вверх
Akella
Дата 2.9.2011, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


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

Репутация: 36
Всего: 329



Цитата(Cinemaizer[Олег)
, 2.9.2011,  13:39, post2396823]Я уже говорил - эскизы делаю именно затем, чтобы не хранить в БД большие картинки

Я спрашивал не зачем тебе нужны эскизы, а зачем такой сложный код, если есть проще? smile

Добавлено @ 13:58
Цитата
Код dll-ки такой:


а вот что тебе советеют разработчики Дельфи smile
Цитата(rodnover @  1.9.2011,  11:00 Найти цитируемый пост)
{ 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. }


Добавлено через 3 минуты и 14 секунд
Цитата(Akella @  2.9.2011,  13:56 Найти цитируемый пост)
ShareMem must be the
  first unit in your library's USES clause AND your project's


попытайся перевести, а потом сравни свои секции USES в DPR модулях проекта и библиотеки.
PM MAIL   Вверх
Cinemaizer[Олег]
Дата 2.9.2011, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 10.4.2008
Где: Москва

Репутация: нет
Всего: 0



Цитата(Akella @  2.9.2011,  11:56 Найти цитируемый пост)
попытайся перевести, а потом сравни свои секции USES в DPR модулях проекта и библиотеки. 

Ок, мастер-йода  smile 
PM MAIL WWW   Вверх
Akella
Дата 2.9.2011, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


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

Репутация: 36
Всего: 329



Ну и... smile
PM MAIL   Вверх
Cinemaizer[Олег]
Дата 2.9.2011, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 10.4.2008
Где: Москва

Репутация: нет
Всего: 0



Цитата(Akella @  2.9.2011,  15:17 Найти цитируемый пост)
Ну и...  

Олл из супербл унд крутэбл smile
В смысле, все починил, все работает! За верное направление благодарю, мастер-йода  smile 
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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