Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.10.22;
Скачать: [xml.tar.bz2];

Вниз

Как через iStream передавать данные в dll и получать обратно?   Найти похожие ветки 

 
or   (2006-09-26 01:16) [0]

Есть TMemoryStream, с моими данными. Надо как то перекинуть их в iStream, отправить в dll, там обработать, вернуть обратно, и переписать обратно в TMemoryStream. Нет ли какого нибудь примера, как это можно сделать ?

Использую iStream потому, что он есть и в Си.


 
or   (2006-09-26 01:27) [1]

Документации и примеров в справке Delphi 7 почти нету. В Гугле тоже как-то глухо.


 
or   (2006-09-26 01:35) [2]

iStream описан в Ole2.pas .


 
or   (2006-09-26 06:45) [3]

Товарищи мастера? Помогите, пожалуйста?


 
Сергей М. ©   (2006-09-26 08:18) [4]

Надо понимать, некая DLL-функция, которую ты хочешь вызвать, требует одним из параметров именно IStream ?

Приведи сишный прототип этой ф-ции ..


 
alex_*** ©   (2006-09-26 13:33) [5]

напиши свой класс, отнаследуй от TMemoryStream и реализуй в нем iStream. Как-то так, видимо


 
or   (2006-09-27 02:06) [6]


> Сергей М. ©   (26.09.06 08:18) [4]
>
> Надо понимать, некая DLL-функция, которую ты хочешь вызвать,
>  требует одним из параметров именно IStream ?
>
> Приведи сишный прототип этой ф-ции ..


Нет. Это я делаю плагины к программе. Мне надо передать в dll большие и сложные данные, переменной длины, а потом получить такие же большие и сложные данные тоже переменной длины.

Мне сказали, что для этого можно использовать iStream, потому, что он есть и в Си и в Дельфи. Поэтому я написал две функции, паковки и распаковки данных в/из потока TMemoryStream. И вот теперь интересютсь как мне их передать через iStream.

Если есть какой то другой способ решения этой задачи, без iStream, но чтобы работал и в Си и в Дельфи, то какой ?


 
Percent   (2006-09-27 02:11) [7]

См. TOLEStream

var
 OS: TOleStream;
 MS: TMemoryStream;
 Stream: IStream;
...
 OS := TOLEStream.Create(Stream);
 try
   MS.CopyFrom(OS, OS.Size);
 finally
   OS.Free;
 end;


 
or   (2006-09-27 02:19) [8]


> Percent   (27.09.06 02:11) [7]

Спасибо!

А как должна выглядеть функция в DLL, которая бы так принимала и возвращала поток ?


 
Percent   (2006-09-27 02:25) [9]

procedure ProcessStream(a_Stream: IStream); stdcall;
var
 OS: TOleStream;
begin
 OS := TOLEStream.Create(a_Stream);
 try
   // работа с потоком "OS" - запись, чтение
 finally
   OS.Free;
 end;
end;


 
Percent   (2006-09-27 02:30) [10]

То есть, если поток a_Stream при вызове процедуры еще не существует, то его надо создать, а потом еще и вернуть - через var или out параметр, или как результат функции.


 
or   (2006-09-27 02:34) [11]

Спасибо, попробую !

А TOLEStream - точно в Си и Си++ поддерживается?

И в этом коде создавать IStream не надо?


var
OS: TOleStream;
MS: TMemoryStream;
Stream: IStream;
...
OS := TOLEStream.Create(Stream);


 
or   (2006-09-27 02:38) [12]


> 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;


 
Percent   (2006-09-27 02:40) [13]

А TOLEStream - точно в Си и Си++ поддерживается?

Это класс Delphi. Он используется для унификации работы с потоками. Порожден от TStream. Читайте справку.

И в этом коде создавать IStream не надо?

За вас создавать поток никто не будет.


 
Percent   (2006-09-27 02:45) [14]

if a_Stream = nil then begin
  a_Stream := TOLEStream.Create(Stream);
end;


Чем по-вашему, отличаются TOleStream и IStream?
Создание экземпляра IStream - используя функцию CreateStreamOnHGlobal()

P.S. Ложитесь спать.


 
or   (2006-09-27 02:51) [15]


> 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 04:03) [16]

А что надо ей передавать в качестве hglob ?

В вашем случае - 0. Скорее всего. Я не знаю, что вы там пишете.

P.S. Жмите хоть иногда F1 - говорят, помогает.


 
or   (2006-09-28 01:53) [17]

У меня наконец получилось. Спасибо ещё раз !


 
Slym ©   (2006-09-28 04:22) [18]

УУУ... а зачем так сложно?
Stream:=TMemoryStream;
is:=TStreamAdapter.Create(Stream,soOwned);
Не надо - Stream.Free как только RefCount=0 сразу поток и освободится...


 
or   (2006-09-28 05:17) [19]


> 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 в Линуксе есть? Так, на будущее.


 
or   (2006-09-29 02:32) [20]

Как с размером то быть ? Никто не в курсе ?


 
evvcom ©   (2006-09-29 09:14) [21]

> [20] or   (29.09.06 02:32)

Так тебе шашечки или ехать? (с) Анекдот


 
or   (2006-09-30 03:32) [22]

Что тут форум анекдотчиков чтоли ?


 
Percent   (2006-09-30 11:16) [23]

Stream:=TMemoryStream;
is:=TStreamAdapter.Create(Stream,soOwned);


Опасно.

CreateStreamOnHGlobal и TMemoryStream.Create - почувствуйте разницу.
Что произойдет при выгрузке DLL, если TMemoryStream был в ней (DLL) создан, но все еще используется в основной программе или другом модуле?

А то на ровном месте, и такой рост размера.

Если просмотреть исходный текст подключенных модулей (ActiveX и AxCtrls), то сразу станет видно, что это не "ровное место", а весьма сложный механизм. Реализован он за вас другими программистами - вам радоваться надо бы, а не сетовать...

И ActiveX в Линуксе есть?

Вообще-то, ActiveX - Windows-технология...


 
or   (2006-10-01 04:05) [24]


> Percent   (30.09.06 11:16) [23]
> И ActiveX в Линуксе есть?
> Вообще-то, ActiveX - Windows-технология...

Ну может аналог там какой есть, мало ли?
Потому, что если это небудет работать в Линуксе ( так, на будущее ), то сразу большой минус.

А нельзя передавать данные не через iStream, а динамическим массивом?
Так, чтоб dll могла менять его размер писать свои данные и возвращать?


 
Percent   (2006-10-01 10:13) [25]

(Почти) классика:

Например, в 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-02 04:17) [26]


> Percent   (01.10.06 10:13) [25]

А если в DLL форма с настройками всякими ? Пользователь их выбирает, кликает, а памяти нехватило, и у него опять появляется форма где заново нужно всё выбирать.

Так, что наверное это не подходит.


 
evvcom ©   (2006-10-02 10:49) [27]

> [22] or   (30.09.06 03:32)

:-) Так ты и иносказаний не понимаешь? Заметь, не был рассказан анекдот целиком, а только процитирован ключевой вопрос.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2006.10.22;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.041 c
15-1159546902
Desdechado
2006-09-29 20:21
2006.10.22
Программа для включения задизабленных кнопок


15-1159686860
Kerk
2006-10-01 11:14
2006.10.22
Олигархи


3-1156846974
Дырчик
2006-08-29 14:22
2006.10.22
Как запаковать таблицу


2-1160305195
mfender
2006-10-08 14:59
2006.10.22
Actual и formal var


2-1159846925
vegarulez
2006-10-03 07:42
2006.10.22
Как сделать так чтобы форма была поверх всех остальных окон.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский