Люди, подскажите, как сделать, чтобы функция DLL возвращала как результат TBitmap?
Если описать её возвращаемое значение через OleVariant, какая-то путаница выходит
Здравствуйте, bask, Вы писали:
B>Люди, подскажите, как сделать, чтобы функция DLL возвращала как результат TBitmap? B>Если описать её возвращаемое значение через OleVariant, какая-то путаница выходит
Возможно, лучше возвращать поток (наследник TStream), а из потока уже считывать битмап через метод LoadFromStream в программе?
Здравствуйте, bask, Вы писали:
B>Люди, подскажите, как сделать, чтобы функция DLL возвращала как результат TBitmap? B>Если описать её возвращаемое значение через OleVariant, какая-то путаница выходит
Возвращайте хэндл битмапа, только будьте внимательны с выделением памяти — это просто набросок:
function GetBitmapHandle: THandle; external 'bmpDll.dll';
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Image1.Picture.Bitmap.Handle:= GetBitmapHandle;
end;
end.
library bmpDll;
uses
SysUtils,
Classes, Graphics;
var
Bitmap: TBitmap;
function GetBitmapHandle: THandle;
begin
Bitmap:= TBitmap.Create;
Bitmap.LoadFromFile('BRUSH.BMP');
Result:= Bitmap.Handle;
end;
exports
GetBitmapHandle;
begin
end.
---
The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true
Спасибо. да, так получилось.
Но мне надо передать содержимое этого битмапа в бинарном виде для того, чтобы в ASP вывести картинку:
bmp = MyDLLImage.Image //это то самое возвращаемое значение
Response.WriteBinary bmp
Здравствуйте, alex_beast, Вы писали:
_>Здравствуйте, bask, Вы писали:
B>>Люди, подскажите, как сделать, чтобы функция DLL возвращала как результат TBitmap? B>>Если описать её возвращаемое значение через OleVariant, какая-то путаница выходит
_>Возможно, лучше возвращать поток (наследник TStream), а из потока уже считывать битмап через метод LoadFromStream в программе?
Кажется, это то, что надо, буду копать в этом направлении. Спасибо
Здравствуйте, bask, Вы писали:
B>Но мне надо передать содержимое этого битмапа в бинарном виде
Ну тогда как-то так:
library bmpDll;
uses
SysUtils,
Classes, Graphics;
var
Bitmap: TBitmap;
Stream: TMemoryStream;
function GetBitmap(var Buffer; var BufferSize: Integer): Boolean;
begin
Result:= False;
Bitmap:= TBitmap.Create;
try
Bitmap.LoadFromFile('BRUSH.BMP');
Stream:= TMemoryStream.Create;
try
Bitmap.SaveToStream(Stream);
if (BufferSize > 0) and (Stream.Size <= BufferSize) then begin
Stream.Position:= 0;
Stream.ReadBuffer(Buffer, Stream.Size);
Result:= True;
end;
BufferSize:= Stream.Size;
finally
Stream.Free;
end;
finally
Bitmap.Free;
end;
end;
exports
GetBitmap;
begin
end.
Как это использовать в ASP не знаю, в Delphi так:
function GetBitmap(var Buffer; var BufferSize: Integer): Boolean; external'bmpDll.dll';
implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
Stream: TStream;
BufSize1, BufSize2: Integer;
Buffer: Pointer;
begin
BufSize1:= 0;
if not GetBitmap(Buffer^, BufSize1) then begin
if BufSize1 > 0 then begin
GetMem(Buffer, BufSize1);
try
BufSize2:= BufSize1;
if GetBitmap(Buffer^, BufSize2) then begin
Stream:= TMemoryStream.Create;
// Stream:= TFileStream.Create('tmp.bmp', fmCreate);try
Stream.WriteBuffer(Buffer^, BufSize2);
Stream.Position:= 0;
Image1.Picture.Bitmap.LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
finally
FreeMem(Buffer, BufSize1);
end;
end;
end;
end;
---
The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true
Здравствуйте, Danchik, Вы писали:
D>Не учите человека работать с памятью неправильно (в DLL). Выделили память одним менеджером памяти, удалили вторым. D>AV — гарантирован.
Да ну? Укажите конкретно, где именно память выделена одним менеджером, а удалена другим.
---
The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true
Здравствуйте, wallaby, Вы писали:
W>Здравствуйте, Danchik, Вы писали:
D>>Не учите человека работать с памятью неправильно (в DLL). Выделили память одним менеджером памяти, удалили вторым. D>>AV — гарантирован.
W>Да ну? Укажите конкретно, где именно память выделена одним менеджером, а удалена другим.
Здравствуйте, alex_beast, Вы писали:
_>Здравствуйте, bask, Вы писали:
B>>Люди, подскажите, как сделать, чтобы функция DLL возвращала как результат TBitmap? B>>Если описать её возвращаемое значение через OleVariant, какая-то путаница выходит
_>Возможно, лучше возвращать поток (наследник TStream), а из потока уже считывать битмап через метод LoadFromStream в программе?
Не самый хороший совет.
Не нужно никогда явно передавать дельфийские объекты.
Потому что это источник трудноуловимых ошибок.
Засада заключается вот в чём:
Например, объявили мы некий TMyClass.
VMT и прочие параметры этого класса, включая размер, будут вкомпилированы и в вызывающий модуль, и в вызываемый. Т.е. фактически это два класса, просто они одинаковые.
А проблемы начинаются тогда, когда мы что-то в класс добавляем. Меняется размер, меняется VMT — и например программа начинает валиться при использовании плагинов предыдущей версии и т.д.
В случае с TStream работать всё, наверное, будет (это +/- стабильный класс) — но это неправильно всё равно.
Если нужно передавать что-то, имеющее функциональность (как объекты), нужно пользоваться интерфейсами. И передавать именно интерфейсы.
В рассматриваемом случае я бы передавал SAFEARRAY, набитый данными с картинкой.
Нужно только посмотреть, как будет с производительностью (только при необходимости, например обращения частые и картинки большие).
p.s. Аналогично, не нужно использовать string в качестве параметров. Несмотря на наличие борландовского менеджера памяти (который уже менялся, кстати).
Передавайте стандартный COM-овский тип BSTR и будет счастье.
Здравствуйте, Dimentiy, Вы писали:
D>Например, объявили мы некий TMyClass. D>VMT и прочие параметры этого класса, включая размер, будут вкомпилированы и в вызывающий модуль, и в вызываемый. Т.е. фактически это два класса, просто они одинаковые.
Либо ОБЯЗАТЕЛЬНО помещать TMyClass в отдельный пакет (в случае Delphi). Тогда это будет действительно один класс, а не два одинаковых.
Но это из серии "голь на выдумки хитра". Придёт вместо вас человек, не знающий о такой феньке -, уберёт опцию использования пакетов — и привет.
Здравствуйте, Leonid Troyanovsky, Вы писали:
LT>Здравствуйте, bask, Вы писали:
B>>Спасибо, конечно. Но всё не то
LT>А ты б поделился, откуда дровишки. LT>Может быть, тебе и TBitmap.LoadFromResourceName(ID) хватит
В общем, есть давно написанная программа, рисующая графики на TBitmap.
Нужно использовать их в ASP-страницах, для этого надо просто переделать её в dll-функиию, которая вернёт это изображение.
В ASP код будет выглядеть примерно так:
<%@ Language=VBScript%>
<%
Response.ContentType = "image/JPEG"
Set oImage = Server.CreateObject("MyImage.MyImage")
Response.BinaryWrite oImage.Image 'Image - собственно, само изображение в бинарном виде
Set Image = Nothing
%>
Здравствуйте, Danchik, Вы писали:
D>Здравствуйте, bask, Вы писали:
B>>Спасибо, конечно. Но всё не то
D>Google — кладезь информации. Запомните это и ищите сначала там D>http://steveorr.net/articles/ImproveYourImages.aspx D>Или задавайте вопросы в нужном форуме.
Здравствуйте, bask, Вы писали:
D>>Google — кладезь информации. Запомните это и ищите сначала там D>>http://steveorr.net/articles/ImproveYourImages.aspx D>>Или задавайте вопросы в нужном форуме.
B>Google не помогает. B>Мне не нужны примеры на.NET
Здравствуйте, Leonid Troyanovsky, Вы писали:
LT>Здравствуйте, bask, Вы писали:
B>>Response.ContentType = "image/JPEG"
LT>Сие мне непонятно: image/JPEG vs TBitmap