|
CString::Format!
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow Never mind - my own stupidity is the source of every "problem" - Mixture
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
Support CRY- Child Relief and You
|
|
|
|
|
I write to a file by setting CFile::shareDenyWrite, and then try to read it. How can I check if this file is still being written before I open it to read?
Thanks
|
|
|
|
|
CFile::Write() does not return until it has finished. You can call Read() anytime after that.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Thanks a lot for the reply.
I want to call read after the write is done because I need to read some info that locates at the end of the file. In this case, can I check if the write is done before read?
Thanks again!
|
|
|
|
|
panrunling wrote: In this case, can I check if the write is done before read?
What's to check? Write() is a synchronous operation.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
:(When I am trying to launch help file (.chm file) from within x64 release build using winapi htmlhelpa, it gives error "filename.chm not a windows help file, or the file is corrupted". The same code works for win32 release build. Please advise.
|
|
|
|
|
Hi,
I need very fast serialization to disk of a large object (64 MB/128 MB etc). Serializing members one by one is not an option (Boost serialization for example is very slow), and the object does need to be shared across systems so I don't need to worry about endianness. Here's what I came up with:
void saveVoxels(Voxels * voxelData, const char * fileName) throw(...)
{
using namespace std;
ofstream file (fileName, ios::out | ios::binary);
if (file.is_open())
{
file.write((char *)voxelData, sizeof(Voxels));
unsigned int size = voxelData->m_sliceWidth * voxelData->m_sliceHeight * voxelData->m_numSlices * sizeof(unsigned short);
file.write((char *)voxelData->m_pTexture, size);
file.close();
}
}
Voxels* loadVoxels(const char * fileName) throw(...)
{
using namespace std;
ifstream file(fileName, ios::in | ios::binary | ios::ate);
if (file.is_open())
{
unsigned long size = file.tellg();
char * memblock = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();
Voxels * voxelData = (Voxels *) memblock;
voxelData->m_pTexture = (unsigned short *) (memblock + sizeof(Voxels));
return voxelData;
}
}
Which as far as I can tell works. However when deleting the object I get _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) assertion error. I guess I didn't really allocate the m_pTexture pointer which is what gets deleted...Any solutions?
|
|
|
|
|
have you tried something like: KLV?[^]. It is just a form of binary serialization, but we shoot videos to file or across the net using it.
_________________________
Asu no koto o ieba, tenjo de nezumi ga warau.
Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
|
|
|
|
|
Budric B. wrote: However when deleting the object I get _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) assertion error.
Does the pointer ever get moved? In other words, if you did something like:
char *p = new char[5];
p++;
delete [] p; the result would not be what you'd expect because a different address is being freed.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
No, the pointers does not get moved. Voxels is a class and it gets returned from the loadVoxels() function. The problem is when I call "delete Voxels;" the destructor is deleting the member array and that's when the assertion fails.
|
|
|
|
|
Budric B. wrote: The problem is when I call "delete Voxels;"...
Which should be:
delete [] Voxels;
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
I see...even though it's an object? I know I'm casting an array to an object, but I would have thought things would behave as they would for any object created with new.
|
|
|
|
|
Well, it wouldn't hurt to try. If it doesn't work, you're no worse off.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
I'm probably wrong, but at first glabce something seems fishy here....
When you write you do this
file.write((char *)voxelData->m_pTexture, size); When you read you do this
Voxels * voxelData = (Voxels *) memblock;
voxelData->m_pTexture = (unsigned short *) (memblock + sizeof(Voxels));
Is there a discrepancy there?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
No,
I first write the object, which contains the data members and a pointer at the end. The size of the object is sizeof(Voxels).
I then write the array of stuff.
When I read, I read everything. I know that the first sizeof(Voxels) bytes is the object including a pointer with a value that's meaningless. I then assign the pointer to point to the data, which just happens to be right after the object (because that's where I read it into).
|
|
|
|
|
What is the reason that you do not have save/load as members of the Voxel class that then manages the internal char*
??
|
|
|
|
|
I get the impresion that Voxels is an object with actual behavior, and therefore shouldn't be written to a file like that. Things like virtual function table pointers can't be saved and restored that way. Also, it looks like Voxels is a relatively small object with a pointer to a huge array, so you wouldn't lose much performance by saving the simple members of Voxels individually. I would save the simple members of Voxels first and then save the array with one file.write call. To restore it, I'd create a Voxels object, read the simple members, and then allocate and read the array.
Also, I noticed you are using unsigned int for the size to write to the file. If you use size_t, the type will be adjusted properly if you migrate to a 64 bit system.
Nathan
|
|
|
|
|
It doesn't have that much behavior other than a constructor and a destructor to free the memory. The reason I was doing it this way was because I would be adding more data members to describe the data later. But you're probably right that it wouldn't add that much performance loss to write each data member. I'll have to time it and see.
I've made a workaround where I allocate 2 buffers, 1 for the object and one for the data, the rest of the code stays the same. That doesn't trigger the assertion. However I don't know if the object's memory gets freed or not since I'm still calling delete Voxels and not delete [] voxels;
|
|
|
|
|
Budric B. wrote: It doesn't have that much behavior other than a constructor and a destructor to free the memory. The reason I was doing it this way was because I would be adding more data members to describe the data later. But you're probably right that it wouldn't add that much performance loss to write each data member. I'll have to time it and see.
Watch out for the copy constructor and assignment operator, since the compiler will generate invalid forms and call them freely.
Budric B. wrote: I've made a workaround where I allocate 2 buffers, 1 for the object and one for the data, the rest of the code stays the same. That doesn't trigger the assertion. However I don't know if the object's memory gets freed or not since I'm still calling delete Voxels and not delete [] voxels;
I think that should work. The main difference between delete and delete[] is the way destructors are called, which shouldn't be a problem if it's just data.
Nathan
|
|
|
|
|
Is it possible to trap DDE messages from the shell?
I mean when a file is opened and it's open method is a DDE command rather than a command line. I have been trying to use SetWindowsHookEx() with no success so far, just wanted to see if I was fighting a lost battle.
|
|
|
|
|
I dont know about "trapping" them but you can monitor them. See the DDESpy Tool, it should have been installed in your Visual Studio/Common/Tools directory, the sources are available as a sample also.
|
|
|
|
|
I have tried DDESpy and I can see the conversation when I load something like Excel document but what I am trying to do is see the messages when something like a .GIF's 'open' verb is invoked which uses DDE to open it with 'OIS.EXE'.
The ultimate goal is to create a ShellExecuteHook which also works for DDE verbs.
|
|
|
|
|
I'm having the compiler give me
error C2327: 'ABC::m_strErrorMessageText' : is not a type name, static, or enumerator
And this is likely because I'm not putting the code together just the way it wants it.
Here's the code
class ABC
{
public:
CString m_strErrorMessageText;
const char* GetErrorMessageText(){ return ( (const char*)m_strErrorMessageText ); }
class DEF
{
public:
enum tagSource
{ INIT,
TERMINATE,
OPEN,
SQL
} Source;
char m_lpErrorText[256];
DEF(tagSource src){Source = src;}
};
class GHI
{
public:
error-> GHI() { m_strErrorMessageText = "Registry Information is missing. Please run BATCH_CONFIG.EXE to correct."; }
};
This code is to house various exceptions that may occur within a library and I'm trying to let each of the different exception types, DEF, GHI put text into the ABC::m_strErrorMessageText member in anyway they want to. The consumers of the library can then decide what exception types they wish to catch and simply use the ABC::GetErrorMessageText in order to get meaningful information. Any ideas on what I might still need to be doing here? Thanks.
Chris Meech
I am Canadian. [heard in a local bar]
|
|
|
|
|
Chris Meech wrote: GHI() { m_strErrorMessageText = "Registry Information is missing. Please run BATCH_CONFIG.EXE to correct."; }
Well GHI either needs an instance of ABC or you need to make that CString a static member of ABC. However based on your last comments in the post I have doubts about your design.
|
|
|
|
|
Thanks. Based upon your's and Mike's reply, I am going to have rethink my design. As well as remember a little more about nested classes.
Chris Meech
I am Canadian. [heard in a local bar]
|
|
|
|