Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Вызов функции из dll


Автор: Kationchic 8.4.2008, 10:31
Есть функция перевода изображения в полутона:

Код

function img2gray(img:TBitmap):TBitmap;
var I: PRGB;
    coef: array[0..2] of extended;
    x,y: integer;
begin
    coef[0]:=0.2989; coef[1]:=0.5870; coef[2]:=0.1140;
    for y:= 0 to img.Height-1 do
    begin
      I := img.ScanLine[y];
      for x:= 0 to img.Width-1 do
      begin
        I[x].rgbtRed  :=check(round(I[x].rgbtRed*coef[0])+round(I[x].rgbtGreen*coef[1])+round(I[x].rgbtBlue*coef[2]));
        I[x].rgbtGreen:=I[x].rgbtRed;
        I[x].rgbtBlue :=I[x].rgbtRed;
      end;
    end;
    result:= img;
end;


Если я вызываю её просто из модуля она хорошо работает... но если вызываю её из dll, начинает громко ругаться матом. 
Что делать?

Автор: Wolfgan 8.4.2008, 10:59
Ты почитай как правильно вызывать функцию из DLL. Точно не помню, но там нужно помоему с директивой stadartcall вызывать.

Автор: Kationchic 8.4.2008, 11:07
Вызываю правильно - остальные функции пашут, но именно эта - нет

Автор: Mikh@il 8.4.2008, 11:20
Твоя функция использует еще функцию check, которая ведет контроль выхода за пределы [0..255].  Про нее ты ничего не написал где она храниться, откуда вызывается. А ошибка твоя скорее всего в том, что вызываемая функция не может найти твою вторую check.

Автор: Kationchic 8.4.2008, 11:38
=( Закоментировала совсем вызов этой функции - все равно вылетает...
Я думаю, что летит на I := img.ScanLine[y]; потому что битмап как-то косо передается... но не знаю как это наверняка проверить или как обойти....

Автор: Mikh@il 8.4.2008, 11:44
Кстати для корректной работы твоей функции изображение должно быть 24bit.
т.е.  Pixelformat:=pf24bit.

Есть такое в твоем коде?

Автор: Kationchic 8.4.2008, 11:46
Нет, спасибо, что сказали - сейчас вставлю

Добавлено через 6 минут и 15 секунд
Вставила :
Код

if (img.PixelFormat<> pf24bit) then exit;

от ошибки не спасло

Автор: Alexeis 8.4.2008, 11:58
  Мдя... очередной раз не заметили граблей  smile . Объекты нельзя передавать из Dll или в Dll. Все это строго запрещено. Можно только COM/ActiveX получать интерфейс объекта либо использовать bpl.

Автор: Kationchic 8.4.2008, 12:07
Но у меня есть функция в той же длл
procedure   doScaled(var img: TImage; sc: extended);
и она работает!


Автор: Mikh@il 8.4.2008, 12:11
Сделай так:
Код


function img2gray(img:TBitmap):TBitmap;
var I:PByteArray;
    x,y: integer;
 function Set255(z:integer):integer;
  begin
   if z>255  then result:=255  else
     if z<0 then result:=0 else result:=z;

  end;
begin
     img.PixelFormat:=pf24bit;
    for y:= 0 to img.Height-1 do
    begin
      I := img.ScanLine[y];
      for x:=1 to 3*img.Width-1 do
      if (x mod 3=0) then
      begin
        I[x-3]:=Set255(round(0.11*I[x-3]+0.5870*I[x-2]+0.2989*I[x-1]));
        I[x-2]:=I[x-3];
        I[x-1]:=I[x-3];
       end;
    end;
end;




Вызов функции:

Код


img2gray(Image1.Picture.Bitmap);
 Image1.Refresh;


Автор: Kationchic 8.4.2008, 12:16
Спасибо

Автор: Alexeis 8.4.2008, 12:18
Цитата(Kationchic @  8.4.2008,  11:07 Найти цитируемый пост)
Но у меня есть функция в той же длл
procedure   doScaled(var img: TImage; sc: extended);
и она работает! 

  Это ровным счетом ничего не значит. Строго запрещено, как раз потому что последствия очень сложно предугадать. В одном месте сработало, а в другом сдохло. Так оно будет всегда, и без всякой причины. То там то тут AV. Приятного вам  smile .

Автор: MetalFan 8.4.2008, 12:35
Цитата(Kationchic @  8.4.2008,  12:07 Найти цитируемый пост)
Но у меня есть функция в той же длл
procedure   doScaled(var img: TImage; sc: extended);
и она работает! 

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

Автор: Kationchic 8.4.2008, 12:44
Ясно... спасибо за информацию.

Автор: pseud 9.4.2008, 11:44
Цитата(Kationchic @  8.4.2008,  12:44 Найти цитируемый пост)
Ясно... спасибо за информацию.


и все же и я выскажусь.

предлагаю передать картинку через строку.

Код

procedure TForm1.Button1Click(Sender: TObject);
var
  strmString: TStringStream;
  s: string;
begin
  strmString := TStringStream.Create('');
  try
    Image1.Picture.Bitmap.SaveToStream(strmString);
    s := strmString.DataString;
    // посылаем эту строку в нашу функцию
    // там в обратную сторону получаем TStringStream
    // из него - TBitmap
    // обрабатываем и возвращаем из функции тоже строку
    // которою -> TStringStream -> TBitmap
    // отображаем в нашем Image
  finally
    strmString.Free;
  end;
end;

Автор: MetalFan 9.4.2008, 12:44
pseud, не идеальный вариант. который скорее всего опять же приведет к неправильному выделению/освобождению памяти в приложении/длл

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)