![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как через iStream передавать данные в dll и получать обратно? [D7]
or © (2006-09-26 01:16:00)Есть TMemoryStream, с моими данными. Надо как то перекинуть их в iStream, отправить в dll, там обработать, вернуть обратно, и переписать обратно в TMemoryStream. Нет ли какого нибудь примера, как это можно сделать ?
Использую iStream потому, что он есть и в Си.
evvcom (2006-10-02 10:49:00) [1]> [22] or (30.09.06 03:32)
:-) Так ты и иносказаний не понимаешь? Заметь, не был рассказан анекдот целиком, а только процитирован ключевой вопрос.
or (2006-10-02 04:17:00) [2]
> Percent (01.10.06 10:13) [25]
А если в DLL форма с настройками всякими ? Пользователь их выбирает, кликает, а памяти нехватило, и у него опять появляется форма где заново нужно всё выбирать.
Так, что наверное это не подходит.
Percent (2006-10-01 10:13:00) [3](Почти) классика:
Например, в DLL реализована функция, которая возврашает результаты своей работы в динамически выделяемой памяти. Тогда работа с данной функцией производится в два шага.
function DLLProcess(a_Mem: pointer; var a_iSize: integer): integer;
a_Mem - указатель на область памяти, в которой будет возвращен (основной) результат вычислений.
a_iSize - размер этой области памяти.
В функции реализован алгоритм вычисления объема памяти, требуемого для возвращения результата. Если вычисленный объем меньше или равен a_iSize, функция с чистой совестью использует переданный указатель для возвращения результатов своей работы; в этом случае функция возвращает некий код "все нормально", обычно это ненулевое значение. Если же объема участка памяти недостаточно для возвращения результатов работы, функция не выполняет никаких действий, и возвращает код ошибки, мол, мало памяти, а также (в a_iSize)- объем требуемой памяти. В случае такой ошибки, вызывающее приложение должно выделить объем памяти, необходимый для корректной работы функции, и вызвать ее (функцию) снова. При повторном вызове функции памяти будет уже достаточно, и функция "с чистой совестью" воспользуется переданным указателем для передачи реультатов вычислений.
P.S. Первый раз функция обычно вызывается с параметрами a_Mem = nil, a_iSize = 0.
or (2006-10-01 04:05:00) [4]
> Percent (30.09.06 11:16) [23]
> И ActiveX в Линуксе есть?
> Вообще-то, ActiveX - Windows-технология...
Ну может аналог там какой есть, мало ли?
Потому, что если это небудет работать в Линуксе ( так, на будущее ), то сразу большой минус.
А нельзя передавать данные не через iStream, а динамическим массивом?
Так, чтоб dll могла менять его размер писать свои данные и возвращать?
Percent (2006-09-30 11:16:00) [5]Stream:=TMemoryStream;
is:=TStreamAdapter.Create(Stream,soOwned);
Опасно.
CreateStreamOnHGlobal и TMemoryStream.Create - почувствуйте разницу.
Что произойдет при выгрузке DLL, если TMemoryStream был в ней (DLL) создан, но все еще используется в основной программе или другом модуле?
А то на ровном месте, и такой рост размера.
Если просмотреть исходный текст подключенных модулей (ActiveX и AxCtrls), то сразу станет видно, что это не "ровное место", а весьма сложный механизм. Реализован он за вас другими программистами - вам радоваться надо бы, а не сетовать...
И ActiveX в Линуксе есть?
Вообще-то, ActiveX - Windows-технология...
or (2006-09-30 03:32:00) [6]Что тут форум анекдотчиков чтоли ?
evvcom (2006-09-29 09:14:00) [7]> [20] or (29.09.06 02:32)
Так тебе шашечки или ехать? (с) Анекдот
or (2006-09-29 02:32:00) [8]Как с размером то быть ? Никто не в курсе ?
or (2006-09-28 05:17:00) [9]
> Slym © (28.09.06 04:22) [18]
>
> УУУ... а зачем так сложно?
> Stream:=TMemoryStream;
> is:=TStreamAdapter.Create(Stream,soOwned);
> Не надо - Stream.Free как только RefCount=0 сразу поток
> и освободится...
Не знаю. Никогда не пробовал.
Ещё вопрос. У меня после добавления в uses ActiveX и AxCtrls размер dll сразу возрастает с 94720 до 453632. А нельзя как нибудь этого избежать ? А то на ровном месте, и такой рост размера.
И ActiveX в Линуксе есть? Так, на будущее.
Slym (2006-09-28 04:22:00) [10]УУУ... а зачем так сложно?
Stream:=TMemoryStream;
is:=TStreamAdapter.Create(Stream,soOwned);
Не надо - Stream.Free как только RefCount=0 сразу поток и освободится...
or (2006-09-28 01:53:00) [11]У меня наконец получилось. Спасибо ещё раз !
Percent (2006-09-27 04:03:00) [12]А что надо ей передавать в качестве hglob ?
В вашем случае - 0. Скорее всего. Я не знаю, что вы там пишете.
P.S. Жмите хоть иногда F1 - говорят, помогает.
or (2006-09-27 02:51:00) [13]
> Percent (27.09.06 02:45) [14]
>
> if a_Stream = nil then begin
> a_Stream := TOLEStream.Create(Stream);
> end;
>
> Чем по-вашему, отличаются TOleStream и IStream?
Понятия не имею ! Работал только с FileStream и MemoryStream. В них всё просто.
> Создание экземпляра IStream - используя функцию CreateStreamOnHGlobal()
Никогда не использовал.
function CreateStreamOnHGlobal(hglob: HGlobal; fDeleteOnRelease: BOOL;
var stm: IStream): HResult; stdcall;
А что надо ей передавать в качестве hglob ?
Percent (2006-09-27 02:45:00) [14]if a_Stream = nil then begin
a_Stream := TOLEStream.Create(Stream);
end;
Чем по-вашему, отличаются TOleStream и IStream?
Создание экземпляра IStream - используя функцию CreateStreamOnHGlobal()
P.S. Ложитесь спать.
Percent (2006-09-27 02:40:00) [15]А TOLEStream - точно в Си и Си++ поддерживается?
Это класс Delphi. Он используется для унификации работы с потоками. Порожден от TStream. Читайте справку.
И в этом коде создавать IStream не надо?
За вас создавать поток никто не будет.
or (2006-09-27 02:38:00) [16]
> Percent (27.09.06 02:30) [10]
>
> То есть, если поток a_Stream при вызове процедуры еще не
> существует, то его надо создать, а потом еще и вернуть -
> через var или out параметр, или как результат функции.
Создать, например, вот так ?
procedure ProcessStream(a_Stream: IStream); stdcall;
var
OS: TOleStream;
Stream: IStream;
begin
if a_Stream = nil then begin
a_Stream := TOLEStream.Create(Stream);
end;
OS := TOLEStream.Create(a_Stream);
try
// работа с потоком "OS" - запись, чтение
finally
OS.Free;
end;
end;
or (2006-09-27 02:34:00) [17]Спасибо, попробую !
А TOLEStream - точно в Си и Си++ поддерживается?
И в этом коде создавать IStream не надо?
var
OS: TOleStream;
MS: TMemoryStream;
Stream: IStream;
...
OS := TOLEStream.Create(Stream);
Percent (2006-09-27 02:30:00) [18]То есть, если поток a_Stream при вызове процедуры еще не существует, то его надо создать, а потом еще и вернуть - через var или out параметр, или как результат функции.
Percent (2006-09-27 02:25:00) [19]procedure ProcessStream(a_Stream: IStream); stdcall;
var
OS: TOleStream;
begin
OS := TOLEStream.Create(a_Stream);
try
// работа с потоком "OS" - запись, чтение
finally
OS.Free;
end;
end;
or (2006-09-27 02:19:00) [20]
> Percent (27.09.06 02:11) [7]
Спасибо!
А как должна выглядеть функция в DLL, которая бы так принимала и возвращала поток ?