Shared memory with CreateDIBSection
-
Hi all, I want to create a bitmap by the function CreateDIBSection, and share the bitmap with other process. HBITMAP CreateDIBSection( HDC hdc, // handle to DC CONST BITMAPINFO *pbmi, // bitmap data UINT iUsage, // data type indicator VOID **ppvBits, // bit values HANDLE hSection, // handle to file mapping object DWORD dwOffset // offset to bitmap bit values ); Following MSDN, hSection is handle that created by CreateFileMapping. Now I want ask that: in the shared-memory that hold by handle hSection: what is shared data? it is ppvBits?. If not, what is relating between ppvBits and data shared in the memory. I don't see any word in MSDN about this. That is good if anyone give me a sample code. Thank you. The world is not enough!
-
Hi all, I want to create a bitmap by the function CreateDIBSection, and share the bitmap with other process. HBITMAP CreateDIBSection( HDC hdc, // handle to DC CONST BITMAPINFO *pbmi, // bitmap data UINT iUsage, // data type indicator VOID **ppvBits, // bit values HANDLE hSection, // handle to file mapping object DWORD dwOffset // offset to bitmap bit values ); Following MSDN, hSection is handle that created by CreateFileMapping. Now I want ask that: in the shared-memory that hold by handle hSection: what is shared data? it is ppvBits?. If not, what is relating between ppvBits and data shared in the memory. I don't see any word in MSDN about this. That is good if anyone give me a sample code. Thank you. The world is not enough!
You could have a look to these two articles:* A freeware MFC class to encapsulate Memory Mapped Files[^]
Where do you expect us to go when the bombs fall?
-
Hi all, I want to create a bitmap by the function CreateDIBSection, and share the bitmap with other process. HBITMAP CreateDIBSection( HDC hdc, // handle to DC CONST BITMAPINFO *pbmi, // bitmap data UINT iUsage, // data type indicator VOID **ppvBits, // bit values HANDLE hSection, // handle to file mapping object DWORD dwOffset // offset to bitmap bit values ); Following MSDN, hSection is handle that created by CreateFileMapping. Now I want ask that: in the shared-memory that hold by handle hSection: what is shared data? it is ppvBits?. If not, what is relating between ppvBits and data shared in the memory. I don't see any word in MSDN about this. That is good if anyone give me a sample code. Thank you. The world is not enough!
phieu wrote:
what is shared data? it is ppvBits?.
If you've provided a file mapping (hSection) then the data pointed to by ppvBits can be shared through the file mapping. To do that, refer to the links suggested above :) Mark
"If you can dodge a wrench, you can dodge a ball."
-
phieu wrote:
what is shared data? it is ppvBits?.
If you've provided a file mapping (hSection) then the data pointed to by ppvBits can be shared through the file mapping. To do that, refer to the links suggested above :) Mark
"If you can dodge a wrench, you can dodge a ball."
Thanks Mark. OK, Now I see the data pointed to by ppvBits can be shared through the file mapping. But now I don’t know why: error code = 87 (ERROR_INVALID_PARAMETER) when I call CreateDIBSection thought out but bitmap is valid. Someone can tell me why? Thank you. Here is my code: #define BITMAP_MMF_NAME "Global\\PRJ_IMS" HANDLE m_hMMF; HBITMAP m_hBitmap; void CBitmapMMFDlg::OnButton3() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください int nWidth = 100, nHeight = 100; long nSize = nWidth*nHeight*3; // Create a file-mapping m_hMMF = ::CreateFileMapping( (HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, nSize, BITMAP_MMF_NAME); DWORD dw = GetLastError(); if (m_hMMF) { // Create bitmap and map this bitmap to File-mapping m_hBitmap = NULL; HDC hdc = ::GetDC(NULL); // entire screen //off-screen bitmap/image size - width must be DWORD aligned (multiples of 4) LONG sizeImage = ((nWidth * 3 + 3) & 0xfffffffc) * nHeight; BITMAPINFO bmpInfo; memset(&bmpInfo,0,sizeof(bmpInfo)); bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = nWidth; bmpInfo.bmiHeader.biHeight = -nHeight; bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = 24; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biSizeImage = sizeImage ; bmpInfo.bmiHeader.biXPelsPerMeter = 0; bmpInfo.bmiHeader.biYPelsPerMeter = 0; bmpInfo.bmiHeader.biClrUsed = 0; bmpInfo.bmiHeader.biClrImportant = 0; //Create DIB Section - off screen bitmap void* pBits = NULL; DWORD dwOffset = 0; m_hBitmap = CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, &pBits, m_hMMF, dwOffset); TRACE("Error code = %d \n", GetLastError()); // change bitmap bit data -> to test output if(pBits != NULL) { for (int i = 0; i < 30000; i ++) { *((char*)(pBits) +i) = i%255; } } ///////////////////////////////////////////////// // display bitmap if (m_hBitmap != NULL) { CDC* pDC = GetDlgItem(IDC_STATIC)->GetDC(); if (pDC) { CDC dcMem; dcMem.CreateCompatibleDC(pDC); CBitmap* pBmp = CBitmap::FromHandle(m_hBitmap); CBitmap* pOldBmp= dcMem.SelectObject(pBmp); pDC->BitBlt(0,0, 100, 100, &dcMem, 0, 0, SRCCOPY); } } } }
-
Thanks Mark. OK, Now I see the data pointed to by ppvBits can be shared through the file mapping. But now I don’t know why: error code = 87 (ERROR_INVALID_PARAMETER) when I call CreateDIBSection thought out but bitmap is valid. Someone can tell me why? Thank you. Here is my code: #define BITMAP_MMF_NAME "Global\\PRJ_IMS" HANDLE m_hMMF; HBITMAP m_hBitmap; void CBitmapMMFDlg::OnButton3() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください int nWidth = 100, nHeight = 100; long nSize = nWidth*nHeight*3; // Create a file-mapping m_hMMF = ::CreateFileMapping( (HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, nSize, BITMAP_MMF_NAME); DWORD dw = GetLastError(); if (m_hMMF) { // Create bitmap and map this bitmap to File-mapping m_hBitmap = NULL; HDC hdc = ::GetDC(NULL); // entire screen //off-screen bitmap/image size - width must be DWORD aligned (multiples of 4) LONG sizeImage = ((nWidth * 3 + 3) & 0xfffffffc) * nHeight; BITMAPINFO bmpInfo; memset(&bmpInfo,0,sizeof(bmpInfo)); bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = nWidth; bmpInfo.bmiHeader.biHeight = -nHeight; bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = 24; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biSizeImage = sizeImage ; bmpInfo.bmiHeader.biXPelsPerMeter = 0; bmpInfo.bmiHeader.biYPelsPerMeter = 0; bmpInfo.bmiHeader.biClrUsed = 0; bmpInfo.bmiHeader.biClrImportant = 0; //Create DIB Section - off screen bitmap void* pBits = NULL; DWORD dwOffset = 0; m_hBitmap = CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, &pBits, m_hMMF, dwOffset); TRACE("Error code = %d \n", GetLastError()); // change bitmap bit data -> to test output if(pBits != NULL) { for (int i = 0; i < 30000; i ++) { *((char*)(pBits) +i) = i%255; } } ///////////////////////////////////////////////// // display bitmap if (m_hBitmap != NULL) { CDC* pDC = GetDlgItem(IDC_STATIC)->GetDC(); if (pDC) { CDC dcMem; dcMem.CreateCompatibleDC(pDC); CBitmap* pBmp = CBitmap::FromHandle(m_hBitmap); CBitmap* pOldBmp= dcMem.SelectObject(pBmp); pDC->BitBlt(0,0, 100, 100, &dcMem, 0, 0, SRCCOPY); } } } }
I don't see anything right away... Try changing to bmpInfo.bmiHeader.biSizeImage = 0; Also you calculate your file mapping size like this: long nSize = nWidth*nHeight*3; and your bmpInfo.bmiHeader.biSizeImage like this LONG sizeImage = ((nWidth * 3 + 3) & 0xfffffffc) * nHeight; Both should use the same calculation and the second method is better since DIB rows should be aligned to a 4-byte boundary. In this case it's ok with a rowsize of 100 :) Mark
"If you can dodge a wrench, you can dodge a ball."
-
Thanks Mark. OK, Now I see the data pointed to by ppvBits can be shared through the file mapping. But now I don’t know why: error code = 87 (ERROR_INVALID_PARAMETER) when I call CreateDIBSection thought out but bitmap is valid. Someone can tell me why? Thank you. Here is my code: #define BITMAP_MMF_NAME "Global\\PRJ_IMS" HANDLE m_hMMF; HBITMAP m_hBitmap; void CBitmapMMFDlg::OnButton3() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください int nWidth = 100, nHeight = 100; long nSize = nWidth*nHeight*3; // Create a file-mapping m_hMMF = ::CreateFileMapping( (HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, nSize, BITMAP_MMF_NAME); DWORD dw = GetLastError(); if (m_hMMF) { // Create bitmap and map this bitmap to File-mapping m_hBitmap = NULL; HDC hdc = ::GetDC(NULL); // entire screen //off-screen bitmap/image size - width must be DWORD aligned (multiples of 4) LONG sizeImage = ((nWidth * 3 + 3) & 0xfffffffc) * nHeight; BITMAPINFO bmpInfo; memset(&bmpInfo,0,sizeof(bmpInfo)); bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = nWidth; bmpInfo.bmiHeader.biHeight = -nHeight; bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = 24; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biSizeImage = sizeImage ; bmpInfo.bmiHeader.biXPelsPerMeter = 0; bmpInfo.bmiHeader.biYPelsPerMeter = 0; bmpInfo.bmiHeader.biClrUsed = 0; bmpInfo.bmiHeader.biClrImportant = 0; //Create DIB Section - off screen bitmap void* pBits = NULL; DWORD dwOffset = 0; m_hBitmap = CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, &pBits, m_hMMF, dwOffset); TRACE("Error code = %d \n", GetLastError()); // change bitmap bit data -> to test output if(pBits != NULL) { for (int i = 0; i < 30000; i ++) { *((char*)(pBits) +i) = i%255; } } ///////////////////////////////////////////////// // display bitmap if (m_hBitmap != NULL) { CDC* pDC = GetDlgItem(IDC_STATIC)->GetDC(); if (pDC) { CDC dcMem; dcMem.CreateCompatibleDC(pDC); CBitmap* pBmp = CBitmap::FromHandle(m_hBitmap); CBitmap* pOldBmp= dcMem.SelectObject(pBmp); pDC->BitBlt(0,0, 100, 100, &dcMem, 0, 0, SRCCOPY); } } } }
Is m_hBitmap NULL after the CreateDIBSection call?
"If you can dodge a wrench, you can dodge a ball."
-
Is m_hBitmap NULL after the CreateDIBSection call?
"If you can dodge a wrench, you can dodge a ball."
-
m_hBitmap is not NULL, and I can display it ok, but GetLastError() = 87, INVALID_PARAMETER. I don't know why?
If it's not NULL then it was successful and calling GetLastError() isn't necessarily valid. You only need to call that on failure. From the docs: "Most functions that set the thread's last-error code set it when they fail. However, some functions also set the last-error code when they succeed. If the function is not documented to set the last-error code, the value returned by this function is simply the most recent last-error code to have been set; some functions set the last-error code to 0 on success and others do not." Generally errors are checked for and handled something like: m_hBitmap = CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, &pBits, m_hMMF, dwOffset); if (NULL == m_hBitmap) { TRACE("Error code = %d \n", GetLastError()); ...do appropriate error handling/cleanup here }
"If you can dodge a wrench, you can dodge a ball."
-
If it's not NULL then it was successful and calling GetLastError() isn't necessarily valid. You only need to call that on failure. From the docs: "Most functions that set the thread's last-error code set it when they fail. However, some functions also set the last-error code when they succeed. If the function is not documented to set the last-error code, the value returned by this function is simply the most recent last-error code to have been set; some functions set the last-error code to 0 on success and others do not." Generally errors are checked for and handled something like: m_hBitmap = CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, &pBits, m_hMMF, dwOffset); if (NULL == m_hBitmap) { TRACE("Error code = %d \n", GetLastError()); ...do appropriate error handling/cleanup here }
"If you can dodge a wrench, you can dodge a ball."