|
im trying to copy a cimage dib to the clipboard. the second
memcpy fails with a read access violation. can anyone help?
CImage tmpImage = pDoc->m_imageArray[0];
int w = tmpImage.GetWidth();
int h = tmpImage.GetHeight();
int Bpp = tmpImage.GetBPP();
BITMAPINFOHEADER bmInfohdr;
bmInfohdr.biSize = sizeof(BITMAPINFOHEADER);
bmInfohdr.biWidth = w;
bmInfohdr.biHeight = -h;
bmInfohdr.biPlanes = 1;
bmInfohdr.biBitCount = Bpp;
bmInfohdr.biCompression = BI_RGB;
bmInfohdr.biSizeImage = w*h*Bpp;
bmInfohdr.biXPelsPerMeter = 0;
bmInfohdr.biYPelsPerMeter = 0;
bmInfohdr.biClrUsed = 0;
bmInfohdr.biClrImportant = 0;
BITMAPINFO bmInfo;
bmInfo.bmiHeader = bmInfohdr;
bmInfo.bmiColors[0].rgbBlue=255;
void* pBits = tmpImage.GetBits();
HANDLE hData = ::GlobalAlloc (GMEM_MOVEABLE, sizeof(BITMAPINFO) + w * h * 3);
LPVOID pData = (LPVOID) ::GlobalLock (hData);
LPBYTE p_imagebits;
p_imagebits = (LPBYTE)pData + sizeof(BITMAPINFO);
memcpy(pData,&bmInfo,sizeof(BITMAPINFO));
DWORD dwBytes = ((DWORD) w * Bpp) / 32;
if(((DWORD) w * Bpp) % 32) {
dwBytes++;
}
dwBytes *= 4;
unsigned long m_dwSizeImage = dwBytes * h;
memcpy (p_imagebits, pBits, m_dwSizeImage);
::GlobalUnlock (hData);
COleDataSource* pods = new COleDataSource;
pods->CacheGlobalData (CF_DIB, hData);
pods->SetClipboard ();
|
|
|
|
|
It fails because the memory allocated by GlobalAlloc is not enough. See, how you use sizeof(BITMAPINFO) + w * h * 3 value to allocate memory, and then you are trying to calculate the m_dwSizeImage value, which is much greater then requested.
You have got two options:
Either move this chunk of code after you have calculated the image size, so that your code becomes:
DWORD dwBytes = ((DWORD) w * Bpp) / 32;
if(((DWORD) w * Bpp) % 32) {
dwBytes++;
}
dwBytes *= 4;
unsigned long m_dwSizeImage = dwBytes * h;
void* pBits = tmpImage.GetBits();
HANDLE hData = ::GlobalAlloc (GMEM_MOVEABLE, sizeof(BITMAPINFO) + m_dwSizeImage);
LPVOID pData = (LPVOID) ::GlobalLock (hData);
LPBYTE p_imagebits;
p_imagebits = (LPBYTE)pData + sizeof(BITMAPINFO);
memcpy(pData,&bmInfo,sizeof(BITMAPINFO));
memcpy (p_imagebits, pBits, m_dwSizeImage);
Or, just use a solution[^] from Codeguru
BTW, it looks like you have calculated the m_dwImageSize incorrectly anyway
|
|
|
|
|
Code snippet below. The SeekToBegin fails because the CFile object has an invalid file handle. But the open returns true, so the code proceeds to die an ugly death. The code is called within a tight loop passing through a couple of hundred files. It feels like I'm overrunning the hard drive or file system, but I have no idea how I might do that... any thoughts are greatly appreciated.
FilePath = (CString)directoryBuf;
FilePath += (CString)"\\uncompressed.unc";
CFileException fe;
if(UncompFile.Open(FilePath, CFile::shareExclusive | CFile::modeCreate | CFile::modeReadWrite), &fe)
{
UncompFile.SeekToBegin();
UncompFile.Write(outBuf, c_stream.total_out);
UncompFile.SeekToBegin();
UncompFile.Write(outBuf, c_stream.total_out);
UncompFile.Close();
cmpCRC = helper.ComputeFileCRC( FilePath );
UncompFile.Remove((LPCTSTR)FilePath);
if(uncCRC != cmpCRC)
{
ErrorString = (CString)infoStruct->sourceFileName + "\n failed CRC test.";
return ErrorString;
}
Charlie Gilley
<italic>You're going to tell me what I want to know, or I'm going to beat you to death in your own house.
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
modified 10-Oct-12 13:11pm.
|
|
|
|
|
Okay, I made one change. Just prior to the .Close, I now invoke .Flush().
The main difference between my environment and the old environment is that my laptop is much faster with a solid state disk. Is it possible that there is a race condition inside of CFile? Seems like I'm grasping at straws.
Charlie Gilley
<italic>You're going to tell me what I want to know, or I'm going to beat you to death in your own house.
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
Why is this code duplicated?
UncompFile.SeekToBegin();
UncompFile.Write(outBuf, c_stream.total_out);
FYI, Remove() is a static method. It will be correct to call it like this:
CFile::Remove((LPCTSTR)FilePath)
The method Remove() can throw an exception
Example here[^]
|
|
|
|
|
Duplicated code: I don't know. I didn't write this code . Not ducking the question, and it did occur to me that if I was creating a file, the initial position would be zero. In testing, I commented out that line only to have the same exception thrown on the write method - bad file handle.
Static Remove and exceptions: noted.
Charlie Gilley
<italic>You're going to tell me what I want to know, or I'm going to beat you to death in your own house.
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
FilePath = (CString)directoryBuf;
FilePath += (CString)"\\uncompressed.unc";
What is the purpose of the casts in the above statements?
In the rest of your code you are not checking the contents of fe after the open so you cannot be sure you have a valid handle at that point. It is always advisable to check the return status of every function call dealing with files, rather than assuming they all succeed.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
Inherited code, probably done for no particular reason. They're gone now.
Function returns: yup, not going to argue the point.
I'm going to condense this code down to a very tight little application and hammer a hard drive. Adding the flush seemed to stabilize things, but I'm suspicious of memory corruption.
Stay tuned for the next episode of "As the Code turns..." will Charlie find happiness?
Charlie Gilley
<italic>You're going to tell me what I want to know, or I'm going to beat you to death in your own house.
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
Richard - the fe content only becomes important if the open call fails. Note the weirdness, it's returning true yet with an invalid handle. In the debugger, I can see that the content of the file exception structure is "no error".
Charlie Gilley
<italic>You're going to tell me what I want to know, or I'm going to beat you to death in your own house.
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
charlieg wrote: it's returning true yet with an invalid handle. I find that very hard to believe; I think you are perhaps misreading something.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
if(UncompFile.Open(FilePath, ...)
{
UncompFile.SeekToBegin(); // <--- asserts here. bad file handle...
I don't know how I could misread that. I'm all ears or eyes....
Charlie Gilley
<italic>You're going to tell me what I want to know, or I'm going to beat you to death in your own house.
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
charlieg wrote: I don't know how I could misread that. I suspect there is a lot more going on in that code than meets the eye. You cannot open a file successfully and then immediately find that the handle is bad; it implies a serious bug in the Win32 SDK which would affect just about every system on the planet. The reality is that there is a bug in your code that has, as yet, gone undetected, but without a lot more information we cannot begin to guess where it is.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
I completely agree. Reaching for a bug in Win32 is silly....
and apologies to all for putting this question in the wrong friggin forum.
Charlie Gilley
<italic>You're going to tell me what I want to know, or I'm going to beat you to death in your own house.
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
Lose all the casting. The cast to CString is implicit; it's not needed and is ugly. The cast from CString to LPCTSTR is in the same boat. As to your problem, I didn't look, I was distracted by all the unsavoury casting.
Steve
|
|
|
|
|
This is just too funny. sigh, in a sad sort of funny....
So, I have managed to muddle along as there simply is no time to re-write this app. Yet. I can get it to run in the debugger under Windows 7, so that's what I've been doing.
Fast forward three months.
New laptop, new Windows 7 install (should be basically the same, but who really knows?), new VM, etc.
Guess what's running now?
Thumps along just fine. I know the bug is still there, I'm not that dellusional.
Charlie Gilley
<italic>You're going to tell me what I want to know, or I'm going to beat you to death in your own house.
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
First off, I'm still new to coding in C++ and so I hope this is the right forum for my question...
I'm coding a very small utility for a niche need we've got where I work. Right now I've got things coded so that it uses CreateProcess to fire off another program we run. What I need to do is then have this utility stay open and running (the program that it kicks off can terminate the original program once it's done doing its thing - and I can't just wait for a return code because the program that gets kicked off may kick off others, and one of those might be the final item to run).
Right now it launches our program and then, since it's done doing all the code, it finishes up and quits. Is there any way to tell the thing to stay open and running? Kind of like a service (but not a service because I don't want to install anything).
|
|
|
|
|
Just add a loop with a timer, and whatever other functions you need. The sequence would then be something like:
while TRUE
if applicationFlag is TRUE
then
start external application
set applicationFlag FALSE
end if
sleep for some seconds
end while
You will need to add some other decision code to set the applicationFlag to TRUE at some point.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
What if the program remains open for an hour or three (I hope they close it sooner, but I have to think of the "what ifs")? Is the Sleep command going to be the right way to go, or am I going to create a problem when using it over an extended period of time?
|
|
|
|
|
The other alternative is to use a timer: Timers Tutorial[^] is a great article which shows how to implement a few.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
If I'm understanding correctly (I'm not certain I am, your description is anything but clear) something like this might help (you can wait on a process handle):
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
BOOL bOk = CreateProcess(
_T("C:\\Windows\\system32\\notepad.exe"),
NULL,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi
);
if (bOk)
{
CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
MessageBox(NULL, _T("Finished"), _T("Create and wait"), MB_OK);
}
Steve
|
|
|
|
|
I just downloaded the USBView sample application...
http://code.msdn.microsoft.com/windowshardware/USBView-sample-application-e3241039
...and I'm getting a cryptic error when compiling with Visual Studio 2010.
1>------ Rebuild All started: Project: usbview, Configuration: Win8 Debug Win32 ------
1>Build started 10/5/2012 11:58:11 AM.
1>C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\Microsoft.Cpp.Win32.Targets(518,5):
error MSB8008: Specified platform toolset
(WindowsApplicationForDrivers8.0) is not installed or invalid. Please
make sure that a supported PlatformToolset value is selected.
1>
1>Build FAILED.
1> 1>Time Elapsed 00:00:00.16
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
Any thoughts or ideas to resolve this would be appreciated. I'm using Windows 7, 32-bit. Thanks.
|
|
|
|
|
|
Thanks, Wes. I was able to resolve the problem by installing Visual Studio 2012 Express and recommended components, removing the offending line from the Microsoft.Cpp.Platform.targets file (double-clicked error message), and compiling as Release.
|
|
|
|
|
Hello,
I have the multimap :
TranslationTypeMap m_TranslationsMap;
where
typedef std::multimap< std::pair<CString, CString>, structTranslationData> TranslationTypeMap;
and
struct structTranslationData
{
std::wstring wstrTranslationId;
std::wstring wstrTextTranslated;
};
here an example of insertion in this map:
structTranslationData pstTranslationData;
pstTranslationData.wstrTranslationId = xxxx; pstTranslationData.wstrTextTranslated = xxxx;
strIdCaption = yyyy;
strIdLang = zzzz; m_TranslationsMap.insert(std::make_pair( std::make_pair(strIdCaption, strIdLang), pstTranslationData ) );
And finaly I write the code below to free memory used by this multimap:
m_TranslationsMap.erase(m_TranslationsMap.begin(), m_TranslationsMap.end());
can we say that memory is free ?
if not , what is the good way to do this ?
Thank you
|
|
|
|
|
It might depend on the implementation of the multimap. I checked it long ago but if I remember right your erase() call sets back the allocation to a minimum, identical to the allocation performed by the default ctor of multimap (at least in the SGI stl implementation of Visual C++ I used at the time). Note that even newly created empty std containers have a small piece of memory preallocated and some containers (like std::vector) dont shrink the size of the allocated memory area (capacity) even if you erase items.
A trick that seems to reset the allocated memory of any std containers regardless of stl implementation and container type is the following:
typedef std::multimap<int,int> MyMap;
MyMap global_map;
void my_func()
{
MyMap empty_map;
empty_map.swap(global_map);
}
|
|
|
|
|