| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > DLL каким макаром можна вернуть из нее результат |
| Автор: X-Vlad 9.4.2008, 11:16 | ||
| Привет всем. Пишу длл. в ней лежат компоненты которые работают с веб камерой... с программы я ее запускаю появляется окно с длл там нажимаю кнопку делается снимок - мне его надо передать обратно в программу. Как это сделать? пробовал что типа: функция в длл
Из длл вроди нельзя передавать обьекты.. какой есть выход? может стоит юзать МемориСтрим? Может кто нибуть стыкался с подобным? Зарание благодарен. |
| Автор: Alexeis 9.4.2008, 11:33 |
| Если юзается общий менеджер памяти, то можно заюзать обычный array of byte, можно вернуть интерфейс IStream, который получается через TStreamAdapter, а в проге работать уже с IStream. |
| Автор: pseud 9.4.2008, 11:54 |
| смотри мой пост: http://forum.vingrad.ru/index.php?showtopic=205118&view=findpost&p=1472773# там я рекомендовал передавать картинку строкой при помощи преобразований: TBitmap -> TStringStream -> string string -> TStringStream -> TBitmap чувствую, где-то есть подводный камень, но должно работать ))) |
| Автор: MetalFan 9.4.2008, 12:35 |
| pseud, всетаки AnsiString не стоит передавать в/из DLL. стоит прислушаться к совету Alexeis. самый разумный вариант. |
| Автор: X-Vlad 9.4.2008, 12:44 | ||
тоесть в моем варианте должно быть
? |
| Автор: MetalFan 9.4.2008, 12:47 |
| почти. только "поверх" aStream (кстати нелогичное название локальной переменной) надо создать обертку TStreamAdapter |
| Автор: X-Vlad 9.4.2008, 12:54 | ||
можешь поподробней? |
| Автор: Alexeis 9.4.2008, 13:19 | ||||
Ничего сложного
Больше ничего не нужно. Переменную strm можно передавать куда угодно, но главное не забыть после окончания работы занулить ее присвоив nil, иначе созданный объект не уничтожиться. Если TStreamAdapter назначить владельцем aStream, то он в добавок еще aStream уничтожит по окончанию работы.
На той стороне можно сделать такой же адаптер для TMemoryStream или просто вызывать методы интерфейса IStream для передачи данных. |
| Автор: X-Vlad 9.4.2008, 13:39 | ||||
программа
DLL
так? или я чтото непонял? |
| Автор: Rennigth 9.4.2008, 13:54 |
| X-Vlad, 1. раз строки передаешь используешь ли общий менеджер памяти? 2. Функция в dll также должна быть stdcall. Добавлено через 39 секунд п.с. оттально не смотрел... |
| Автор: X-Vlad 9.4.2008, 14:16 |
| что за фишка такая.. добавляю в uses модуль Types, все равно матерится что незнает что такое IStream? |
| Автор: Alexeis 9.4.2008, 14:17 | ||||
X-Vlad, не не так.
1я строчка бесполезная, так как указатель затирается указателем полученным от GetImageFromWebCam.
тоже не проканнает, так как Bitmap.LoadFromStream не умеет тянуть из IStream. Так что одно из 2х, либо создавать временный TMemoryStream и перекачивать в него данные из aStream, или написать своего потомка от TStream который в своих функциях будет вызывать методы IStream. Т.е. в конструкторе он получит указатель на внешний IStream. |
| Автор: X-Vlad 9.4.2008, 14:25 | ||
Alexeis,
что это? |
| Автор: Rennigth 9.4.2008, 14:30 |
| X-Vlad, а делфя у тя какая? |
| Автор: Alexeis 9.4.2008, 14:31 |
| uses AciveX; |
| Автор: X-Vlad 9.4.2008, 14:32 | ||
| ActiveX - не матерится Добавлено @ 14:44
можешь на примере моего кода подсказать как это закодировать? а то я чтото не вьежаю :( |
| Автор: X-Vlad 9.4.2008, 20:16 | ||||
| Alexeis вот код ДЛЛ и самой программы... можешь подправить? Я неработал никогда с TStreamAdapter. Сделал вот так - матерится AV dll
application
помоги плз. |
| Автор: Alexeis 9.4.2008, 20:22 | ||
X-Vlad, попробуй в приложении использовать такой класс. Его нужно создать на основе полученного IStream и дальше использовать для загрузки из потока. Этот класс свои вызовы подменит вызовами из IStream .
|
| Автор: X-Vlad 9.4.2008, 20:26 |
| ты можешь на моем примере показать (наглядно)? извини что туплю :( Учятся как говорится по докам, книгам и чужом коде Если несложно. |
| Автор: Alexeis 9.4.2008, 20:36 | ||||||||||
X-Vlad, у тебя ошибка тут
Объект исполняет интерфейс, но сам интерфейс не является объектом, его можно приводить только к предку, т.е. IUnkown. Вместо этого следует создать экземпляр TExternStream и передать ему указатель на aStream, и дальше в программе использовать экземпляр класса TExternStream. И еще у тебя утечка в Dll тут
В таком виде aStream никто не уничтожит и он осатанеться висеть в памяти, правильно будет так
Добавлено через 3 минуты и 19 секунд Вместо
Нужно
В остальном вроде все верно. Добавлено через 4 минуты и 44 секунды aOut := TMemoryStream.Create; - тоже нужно убрать, эта строчка абсолютно лишняя. Добавлено через 6 минут и 39 секунд В реализации TExternStream могут быть ошибки. Я его проверил только на синтаксис, в действии проверять долго |
| Автор: X-Vlad 9.4.2008, 20:43 | ||||
в программе зделал вот так:
в длл:
ничего незагружается в Image в программе. и вылетает AV на FreeLibrary(LibHandle); в программе подключен ShareMem и в длл. Стоят первые в дпр файлах. в чем грабли? |
| Автор: X-Vlad 9.4.2008, 21:18 |
| ауу |
| Автор: Alexeis 10.4.2008, 00:43 | ||
А ну да, есть еще одна недоработка. Когда происходит запись в поток его указатель смещается в конец. Если потом из него читать, то разумеется ничего не прочтется. Перед чтением следует установить указатель потока в нуль.
Думаю после этого все заработает |
| Автор: X-Vlad 10.4.2008, 12:47 |
| Большое спасибо. Работает. |