Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
8 / 8 / 2
Регистрация: 02.10.2014
Сообщений: 112
1

Вернуть TBitmap из .dll

25.07.2016, 21:16. Показов 1106. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток!
Столкнулся со странным глюком, и как обойти не знаю, точнее не понимаю, чего от меня хотят. Возможно кто то сталкивался.
Есть dll собранная все все в том же RadStudio (10, ибо только там появилась поддержка Desktop Duplication API).
Функции в dll объявлены следующим образом:
C++
1
2
3
4
5
6
7
8
9
10
__declspec(dllexport) TBitmap* __stdcall GetBmpDx(int X, int Y, int width, int height);
__declspec(dllexport) TBitmap* __stdcall GetBmpGdi(HDC hdc, int X, int Y, int width, int height);
 
__declspec(dllexport) TBitmap* __stdcall GetBmpGdi(HDC hdc, int X, int Y, int width, int height)
{
        bitmap->Width = width; // битмап создается ранее, с указанием bitmap->PixelFormat = pf24bit; 
    bitmap->Height = height;
    BitBlt(bitmap->Canvas->Handle, 0, 0, width, height, hdc, X, Y, SRCCOPY);
    return bitmap;
}
GDI была добавлена от безысходности - думал может DirectX глючит - ан нет, глючат обе. Прототипы в самой программе
C++
1
2
TBitmap* (__stdcall *GetBmpDx)(int X, int Y, int width, int height);
TBitmap* (__stdcall *GetBmpGdi)(HDC hdc, int X, int Y, int width, int height);
Так зову:
C++
1
GetBmpGdi = (TBitmap * (__stdcall*)(HDC, int, int, int, int))GetProcAddress(dllhandle, "GetBmpGdi");
И вот в чем парадокс - при использовании нехитрой конструкции:
C++
1
Form2->Image1->Picture->Bitmap = graphicsHelper.GetBitmap(); // это обертка над GetBmpGdi()
Все работает на ура - как с GDI, так и с DirectX.

Но как только пытаюсь провернуть следующее:
C++
1
2
3
4
5
bitmap = new TBitmap; // PixelFormat = pf24bit; 
bitmap = GetBitmap();   // это обертка над GetBmpGdi()
TRGBTriple *ptr;
int y = 1;
ptr = reinterpret_cast<TRGBTriple*>(bitmap->ScanLine[y]);
При попытке скастовать вышибает ошибки - чаще всего неверный дескриптор. Может есть идеи у кого - где я туплю?
Заранее спасибо!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.07.2016, 21:16
Ответы с готовыми решениями:

как вернуть HBITMAP у Graphics::TBitmap
Добрый вечер! Есть функция вставляющая картинки в видео по их хэндлу: HRESULT AddAviFrame(HAVI...

Вернуть HBITMAP из c++ dll
Во общем есть dll, в ней функция которая сохраняет в bmp файл, сохраняет из HBITMAP переменной, как...

Вернуть строку из .dll на С++ в программу на VB 6.0
Перепробовал несколько вариантов. Не получается. Постоянно ошибки. Последний опробованный и не...

Как из c++ dll функции вернуть RGB\ARGB цвет?
Есть функция в ней есть переменная цвета типа COLORREF Подскажите, кто знает, каким образом можно...

10
Модератор
3389 / 2161 / 352
Регистрация: 13.01.2012
Сообщений: 8,380
26.07.2016, 08:19 2
Meoww, в последнем куске инициализация динамически созданным объектом не нужна - указатель все равно затрется после возврата из функции. Ошибка или в том что объект не возвращается или в конвертации - Вы пробовали приводить так обычный объект на своей стороне?

Добавлено через 1 минуту
+а тот ли это класс? Не нужно ли указать Graphics:: ?
0
8 / 8 / 2
Регистрация: 02.10.2014
Сообщений: 112
26.07.2016, 08:40  [ТС] 3
Доброго утра. Класс тот - при указании Graphics:: ничего не меняется. Да, при использовании (не в dll) таким макаром отработано очень много - и всегда без ошибок. Если вы про эту иннициализацию (bitmap = new TBitmap; ) то конечно в коде ее нет - битмап создается один раз в начале.
В том то и дело что битмап возвращается, с хендлом и тд - абсолютно адекватный, насколько позволяют мои знания.
Терзают меня смутные сомнения, что все это каким то макаром связанно с dll, а точнее с библиотекой vcl - очень уж она любит работать только в главном потоке.
Не так много знаю, чтобы судить - пробую разобраться. Обидно, но блин в TImage как то выводит же.
0
Практикантроп
4827 / 2719 / 526
Регистрация: 23.09.2011
Сообщений: 5,778
26.07.2016, 08:41 4
Я обычно инициализирую битмап иначе:
C++
1
2
3
   Graphics::TBitmap *Bmp = new Graphics::TBitmap;
   Bmp->PixelFormat = pf24bit;
   . . .
Может, пригодится?
0
8 / 8 / 2
Регистрация: 02.10.2014
Сообщений: 112
26.07.2016, 08:51  [ТС] 5
Прошу прощения за дубль - еще одна интерестность:
если в программе создается битмап один раз в начале, то
C++
1
    bitmap->SaveToFile("bit.bmp");
работает на ура. Однако, при попытке создавать и удалять такой-же битмап
C++
1
2
3
4
5
6
bitmap = new TBitmap;
bitmap->Width = gRectWindowSize.right;
bitmap->Height = gRectWindowSize.bottom;
........
bitmap->SaveToFile("bit.bmp");
delete(bitmap);
Программа тут же валится с ошибкой доступа к памяти

nick42 - спасибо) (также создаю битмап один раз в начале) не имеет значения какой битмап используется - вылетает. Я уже и через GDI с HBITMAP пробовал - то-же только в профиль
0
Модератор
3389 / 2161 / 352
Регистрация: 13.01.2012
Сообщений: 8,380
26.07.2016, 08:53 6
Meoww, vcl не влияет хотя то что это битмап пикчи имаджа конечно заставляет работать с ним через синхронайз но не думаю что выбивает изза того что его нет
0
8 / 8 / 2
Регистрация: 02.10.2014
Сообщений: 112
26.07.2016, 09:02  [ТС] 7
Просто сталкивался с подобной "плавающей" ошибкой - тут на форуме есть топик - там именно с синхронизацией потока связанно, что к слову очень раздражает - сумасшедшая потеря времени. Оффтоп))) ддлка написанная на шарпе (используется тот же directX только managed), прикрученая ...эм) вообщем подключенная к проекту на с++ через костыль - работает. Но это же не вариант
0
Практикантроп
4827 / 2719 / 526
Регистрация: 23.09.2011
Сообщений: 5,778
26.07.2016, 09:22 8
Цитата Сообщение от Meoww Посмотреть сообщение
при попытке создавать и удалять
Ну, вот такие две кнопки создают и удаляют битмап без проблем (это без длл, конечно)__
C++
1
2
3
4
5
6
7
8
9
10
11
12
void __fastcall TForm1::Button3Click(TObject *Sender)
{
     if(!Bmp) Bmp = new Graphics::TBitmap;
       Bmp->PixelFormat = pf24bit;
       Bmp->Width = 105; Bmp->Height = 105;
       Bmp->SaveToFile("proba.bmp");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
     delete Bmp; Bmp=NULL;
}
Записывается, как и положено, белый квадрат.
0
8 / 8 / 2
Регистрация: 02.10.2014
Сообщений: 112
26.07.2016, 11:14  [ТС] 9
Да это понятно. Все оно работает, пока находится внутри программы, а вот вынес в dll - проблема. Может и смирился бы - но в image же выводит, и вот при доступе к битам - ошибки.

Добавлено через 9 минут
Вот так работает сохранение (понятно что память течет, и доступ к битам один черт не работает, но все же)
C++
1
2
3
Graphics::TBitmap *pBitmap = new Graphics::TBitmap();
pBitmap = GetBitmap();
bitmap->SaveToFile("bmp.bmp");
А вот так уже нет
C++
1
2
3
4
Graphics::TBitmap *pBitmap = new Graphics::TBitmap();
pBitmap = GetBitmap();
bitmap->SaveToFile("bmp.bmp");
delete (pBitmap);
-> Access violation

Что не так!?!?!
0
Практикантроп
4827 / 2719 / 526
Регистрация: 23.09.2011
Сообщений: 5,778
26.07.2016, 11:40 10
А pBitmap = NULL после delete не поможет?
0
8 / 8 / 2
Регистрация: 02.10.2014
Сообщений: 112
26.07.2016, 11:57  [ТС] 11
Неа. Итак, к сожалению, кажется обнаружил очередной глюк. DLL была собрана в rad10 berlin, так как в предыдущих версиях попросту не было хедера DXGI1_2.h. А сам проект ведется, или точнее теперь уже велся, в rad8, из-за тормозов 10-ки на моем, далеко не самом слабом железе. Одним словом - пересобранный проект в rad10 berlin отлично работает, не вызывая никаких ошибок. Итог - очередной глюк.

Приношу свои извинения за беспокойство
0
26.07.2016, 11:57
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.07.2016, 11:57
Помогаю со студенческими работами здесь

Возможно ли вернуть двухмерный массив строк из DLL функции написаной на C++
Собственно есть DLL(на C++), в ней функция, дальше мне собственно нужно что б эта функция...

Tbitmap.create и Tbitmap.scanline
Если после создания bitmap-а загрузить изображение (loadfromfile()) то изменение пикселей через...

Как вернуть параметр атрибута из сборки .dll?
Здравствуйте! У меня есть сборка с тестами .dll, некоторые тесты отмечены Nunit атрибутом ...

Создать dll и вернуть из функции значение строки
вообщем надо на си сделать отдельную длл и вернуть значение а как не умею обьясните

Как вернуть значение (int) из созданной dll?
Есть набор форм, которые я сделал в виде dll. Внутри этой dll расположено дерево, со значениями: ...

Как вернуть переменные из dll обратно в программу?
Есть dll в которой процедура берет несколько целочисленных переменных и оперируя ими изменяет их,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru