如何在主程序和DLL间传递TBitmap对象?(200分)

  • 主题发起人 主题发起人 xifengge
  • 开始时间 开始时间
上面tseug兄弟的方法,我在D7中测试,如果不带包,执行报错,带包,就不报错。。。

算是帮忙测试了
 
小雨哥的方法,在我的D7中,退出时还是会报错?
 
知道了原因,在 Delphi 7 中可以修改 DLL 代码如下:

library Project33;

uses
Windows,
SysUtils,
Classes,
Graphics;

{$R *.res}

procedure DrawIt(const bmp: TBitmap);
var
B:TBitmap;
begin
B:=TBitmap.Create;
try
B.Width:=bmp.Width;
B.Height:=bmp.Height;
BitBlt(B.Canvas.Handle, 0,0,B.Width,B.Height,bmp.Canvas.Handle,0,0,SRCCOPY);
B.Canvas.Pen.Color := clRed;
B.Canvas.Ellipse(10, 10, bmp.Width-10, bmp.Height-10);
BitBlt(bmp.Canvas.Handle, 0,0,B.Width,B.Height,B.Canvas.Handle,0,0,SRCCOPY);
finally
B.Free;
end;
end;

exports DrawIt;

begin
end.

这样修改后,调用就可以随意选择,可以使用 tseug,也可以使用我原来的方法:
(注意: tseug 原来声明的函数导出少了一点点东西 const)

procedure DrawIt(const bmp: TBitmap);external 'project33.dll';

procedure TForm1.EllipseToBitmap(bmp: TBitmap);
var
B:TBitmap;
begin
B:=TBitmap.Create;
try
B.Assign(bmp);
DrawIt(B);
bmp.Assign(B);
finally
B.Free;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
EllipseToBitmap(Image1.Picture.Bitmap);
end;
 
to 小雨哥
你的办法不错,当时没往这个思路上想,只想着共享对象了,见笑。

另外,刚才单步跟踪了一下,并且根据你的提示察看了调用栈,并未发现任何异常。
我又把RTL100.BPL,VCL100.BPL,以及Project33.DLL, Project32.EXE拷贝到U盘上,
在分别在另外两台没有安转过Delphi的计算机上运行,也没有任何错误提示,很是奇怪。
 
我試試,不怎麽太接觸這方面的,
 
小雨哥,果然是高人。呵呵
 
tseug、小雨哥,两位都是高人啊。看了tseug大哥的回复,发现自己只把EXE工程选中了Build with runtime packages , DLL 工程忘记了哎,真对不住啊。重新编译后执行果然OK了,激动的泪流满面ing ......,天啊,我的问题终于解决啦 [:D][:D][:D]

另外看了下小雨哥的办法,发现实际上EXE工程不必改动,只要DLL端改一下就OK了,这样做实际上也是在DLL中复制了一个Bitmap对象,虽然不用发布可恶的BPL包了,但是还是存在大位图吃内存的问题,所以这次还是采用tseug的办法了。

最后再次感谢tseug、感谢小雨哥,感谢帮忙测试的xuegaoyili兄弟,感谢提供别样思路的szf,感谢各位帮顶的兄弟们,感谢CCTV,感谢我的歌迷... 没有你们,俺走不到今天[:D][:D]
 
[:)]接受答案了
 
最后终于理解了 Delphi 新版本上为什么要做内存管理器的更新了,原来这样的问题就是 Delphi 自身特有的 BUG 。尝试 Delphi7 上的解决方法还是在 DLL 上做工作:

procedure DrawIt(const bmp: TBitmap);
var
Canvas: TCanvas;
begin
Canvas := TCanvas.Create;
try
Canvas.Handle := bmp.Canvas.Handle;
Canvas.Pen.Color := clRed;
Canvas.Ellipse(10, 10, bmp.Width-10, bmp.Height-10);
Canvas.Handle := 0;
finally
Canvas.Free;
end;
end;

exports DrawIt;

begin
RegisterClasses(TBitmap; TCanvas);
end.

用这个办法就不存在大位图重新复制一个拷贝的问题了。
 
最后一句是:RegisterClasses([TBitmap, TCanvas]); 呵呵。

小雨哥,果然可行啊[:D][:D][:D]
高,实在是高啊[:D][:D][:D]
 
后退
顶部