|
George_George wrote: No matter whether they contain data member, right?
Yes, if compiler cannot exploit abstract nature of classes.
George_George wrote: I do not quite understand your statement above. Could you show some pseudo code please?
Yes, suppose (the example is naive, but you'll probably get the idea):
class IX: public IUnknown
{
...
virtual ULONG AddRef(){ return ++m_nRef;}
...
};
class IY: public IUnknown
{
...
virtual ULONG AddRef(){ return 1;}
...
};
void main()
{
IUnknown *pUnk = new CA;
int n = pUnk->AddRef();
}
what will be (if the above code compiles) n value?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
Thanks CPallini,
I think I have got your ideas.
You mean even if IUnknown *pUnk = new CA; can compile, then the statement int n = pUnk->AddRef(); will give ambiguity result -- call AddRef of IX or call AddRef of IY? My understanding correct?
regards,
George
|
|
|
|
|
No, I mean that the sample does NOT compile because of the (call AddRef of IX or call AddRef of IY ) ambiguity, i.e. the compiler prevents such weirdness.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
Thanks CPallini,
My question is answered. You are so knowledgeable.
regards,
George
|
|
|
|
|
George_George wrote: My question is answered. You are so knowledgeable.
Thanks , but it isn't true. There is a lot of people far more knowledgeable than me here at CP .
Anyway, thank you again.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
Last December I installed VC2008 Enterprise Edition on one of the Laptops. It clobbered my VC version 5 (VC 97) edition, all Online VC 97 Helpfiles became Unavailable. I decided that Managed Code is not for me, I prefer MFC, particularly because of the Code Base I have developped. I know that VC 97 is not really supported anymore, but for me it worked, and I decided to stay with it, at least untill I can afford an Upgrade.
I Uninstalled VC2008, and even re-installed VC 97. Still No Helpfiles. Anyone seen this before?
Regards,
Bram van Kampen
|
|
|
|
|
I need help with the code for making an mdiform transparent
tony-yeyo
|
|
|
|
|
code to make an Mdiform transparent
tony-yeyo
|
|
|
|
|
Handle the WM_ERASEBKGND Notification[^] and do nothing in the handler code
except return a non-zero value.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hey,
is there any way to wrap text in a CListCtrl Header? I know I can subclass and do some CustomDraw, but with this method I loose the XP style.
Thanks for your help!
|
|
|
|
|
BYTE *pBuf=GetBinaryOfOneJpegFileFromDatabase();
Need to construct a GdiPlus::Image object using the data pointed to by pBuf .
I found a way, but not so efficient
_variant_t varBLOB;
SafeArrayAccessData(varBLOB.parray,(void**)&pBuf);
SafeArrayUnaccessData (varBLOB.parray);
COleStreamFile stmFile;
stmFile.CreateMemoryStream();
stmFile.WriteHuge(pBuf,lDataSize);
IStream *pS=stmFile.GetStream();
m_pImg=::new Image(pS);
The data pointed to by pBuf is copied several times,
so is there an more efficient way?
Thanks.
|
|
|
|
|
followait wrote: is there an more efficient way?
What about using GlobalAlloc() and CreateStreamOnHGlobal() to
create a stream to pass to the Image ctor?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
It must be better,
but there is a problem when call GlobalUnlock
IStream *pStm=NULL;
::CreateStreamOnHGlobal(NULL,TRUE,&pStm);
ULARGE_INTEGER ui;
ui.LowPart=lDataSize+1;
ui.HighPart=0;
HRESULT hr=pStm->SetSize(ui);
HGLOBAL hGlobal=NULL;
::GetHGlobalFromStream(pStm,&hGlobal);
BYTE *pBuf=(BYTE*)::GlobalLock(hGlobal);
::SafeArrayAccessData(varBLOB.parray,(void**)&pBuf);
::SafeArrayUnaccessData (varBLOB.parray);
BOOL b=::GlobalUnlock(hGlobal);
DWORD dw=::GetLastError();
modified on Monday, February 04, 2008 3:35:03 AM
|
|
|
|
|
|
I assume you found this already...
GlobalUnlock():
"If the memory object is still locked after decrementing the lock count,
the return value is a nonzero value. If the memory object is unlocked
after decrementing the lock count, the function returns zero and GetLastError
returns NO_ERROR.
If the function fails, the return value is zero and GetLastError returns a value other than NO_ERROR."
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I would agree with Mr. Salsbery.
IStream* pStream=NULL;
then use
CreateStreamOnHGlobal(NULL,TRUE,&pStream);
then use the streams "Write" method to get the data from the buffer in,
pStream->Write(pBuf,nSize,NULL);
then use Image::FromStream or the constructor as you had been doing.
|
|
|
|
|
Don't forget to initialize COM for this technique.
|
|
|
|
|
Hi everyone!
Would like to ask...
if i have a DLL that implements a function.. this DLL is used by an EXE. can the call to the DLL function by the EXE be done in parallel? say the EXE implements several thread and each of these threads calls the DLL function. or is the call just 1 at a time?
Thanks for any help.
not so newbie
|
|
|
|
|
The short answer is yes. Any number of threads can call a function in a DLL at the same time; the DLL calling mechanism allows this.
The real answer is it depends on the function in the DLL. The DLL function must be designed to be thread-safe. In other words, you must know that the function can be called from multiple threads safely. If the function uses a global resource, it must protect accesses to that resource so that its state isn't changed incorrectly by multiple threads.
If you don't know that the function is thread-safe, you can make it so by writing your own wrapper, something like this:
static CCriticalSection MyFunction_CS;
void Function(...);
void MyFunction(...)
{
MyFunction_CS.Lock();
Function(...);
MyFunction_CS.Unlock();
} Intead of calling Function(...) directly, you call MyFunction(...) which uses a critical section to ensure only a single thread at a time can call Function(...) .
|
|
|
|
|
Hi! thanks so much for the answer.
if the function does not use global resoure and is something like below
void Function(myobj *obj){
myobj* objTemp = new myobj;
objTemp->a = obj->a;
};
will there be a problem if the function is called by multiple threads?
thanks again!
not so newbie
|
|
|
|
|
This depends on the myobj class, and the type of member 'a '. If 'a ' is a simple type (an int for example) then this code is probably thread-safe as it is. If it is something more complicated that has its own assignment operator, then this function might not be safe.
Suppose a is a linked list of items allocated from a global pool. The assignment operator that performs the objTemp->a = obj->a operation would probably need to allocate items from the global pool. That might make this operation and this function not thread-safe.
|
|
|
|
|
sorry but what do you mean by global pool?
thanks.
not so newbie
|
|
|
|
|
A common approach to keeping the size of a data structure limited is to allocate a fixed number of items and place them in a list of their own at the beginning of the program. This list is called the 'pool'. When the program needs a new item, it removes one from the pool. When it's done with the item, it puts it back in the pool. If the pool is ever empty when it needs a new item, it knows that the data structure has reached its size limit and it can react accordingly.
This pool is a global resource. If you were to have multiple threads accessing it, thread 1 could be partway through removing an entry from the pool while thread 2 could attempt to add an entry to the pool. Pointers to the beginning and end of the pool could be set incorrectly. Later accesses might try to get an item from the pool that is really in use elsewhere, or items might be lost instead of being returned to the pool.
|
|
|
|
|
im not sure if i understand what you meant by a the global resource...
however the struct myobj as shown before is created everytime the function is called and sent as a data to a named pipe then the function returns.
will there be a problem in that case?
|
|
|
|
|
A 'global resource' is an object in the program that will be accessed by more than one thread.
|
|
|
|