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

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

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

Студворк — интернет-сервис помощи студентам
Доброго времени суток!
Столкнулся со странным глюком, и как обойти не знаю, точнее не понимаю, чего от меня хотят. Возможно кто то сталкивался.
Есть 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
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.07.2016, 21:16
Ответы с готовыми решениями:

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

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

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

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

Добавлено через 1 минуту
+а тот ли это класс? Не нужно ли указать Graphics:: ?
0
 Аватар для Meoww
8 / 8 / 2
Регистрация: 02.10.2014
Сообщений: 112
26.07.2016, 08:40  [ТС]
Доброго утра. Класс тот - при указании Graphics:: ничего не меняется. Да, при использовании (не в dll) таким макаром отработано очень много - и всегда без ошибок. Если вы про эту иннициализацию (bitmap = new TBitmap; ) то конечно в коде ее нет - битмап создается один раз в начале.
В том то и дело что битмап возвращается, с хендлом и тд - абсолютно адекватный, насколько позволяют мои знания.
Терзают меня смутные сомнения, что все это каким то макаром связанно с dll, а точнее с библиотекой vcl - очень уж она любит работать только в главном потоке.
Не так много знаю, чтобы судить - пробую разобраться. Обидно, но блин в TImage как то выводит же.
0
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
26.07.2016, 08:41
Я обычно инициализирую битмап иначе:
C++
1
2
3
   Graphics::TBitmap *Bmp = new Graphics::TBitmap;
   Bmp->PixelFormat = pf24bit;
   . . .
Может, пригодится?
0
 Аватар для Meoww
8 / 8 / 2
Регистрация: 02.10.2014
Сообщений: 112
26.07.2016, 08:51  [ТС]
Прошу прощения за дубль - еще одна интерестность:
если в программе создается битмап один раз в начале, то
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
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
26.07.2016, 08:53
Meoww, vcl не влияет хотя то что это битмап пикчи имаджа конечно заставляет работать с ним через синхронайз но не думаю что выбивает изза того что его нет
0
 Аватар для Meoww
8 / 8 / 2
Регистрация: 02.10.2014
Сообщений: 112
26.07.2016, 09:02  [ТС]
Просто сталкивался с подобной "плавающей" ошибкой - тут на форуме есть топик - там именно с синхронизацией потока связанно, что к слову очень раздражает - сумасшедшая потеря времени. Оффтоп))) ддлка написанная на шарпе (используется тот же directX только managed), прикрученая ...эм) вообщем подключенная к проекту на с++ через костыль - работает. Но это же не вариант
0
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
26.07.2016, 09:22
Цитата Сообщение от 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
 Аватар для Meoww
8 / 8 / 2
Регистрация: 02.10.2014
Сообщений: 112
26.07.2016, 11:14  [ТС]
Да это понятно. Все оно работает, пока находится внутри программы, а вот вынес в 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
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
26.07.2016, 11:40
А pBitmap = NULL после delete не поможет?
0
 Аватар для Meoww
8 / 8 / 2
Регистрация: 02.10.2014
Сообщений: 112
26.07.2016, 11:57  [ТС]
Неа. Итак, к сожалению, кажется обнаружил очередной глюк. DLL была собрана в rad10 berlin, так как в предыдущих версиях попросту не было хедера DXGI1_2.h. А сам проект ведется, или точнее теперь уже велся, в rad8, из-за тормозов 10-ки на моем, далеко не самом слабом железе. Одним словом - пересобранный проект в rad10 berlin отлично работает, не вызывая никаких ошибок. Итог - очередной глюк.

Приношу свои извинения за беспокойство
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.07.2016, 11:57
Помогаю со студенческими работами здесь

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

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

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

Как вернуть параметр атрибута из сборки .dll?
Здравствуйте! У меня есть сборка с тестами .dll, некоторые тесты отмечены Nunit атрибутом public void test() {}Мне нужно...

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


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит: токи, напряжения и их 1 и 2 производные при t = 0;. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru