|
Thanks CPallini,
I am confused why there is ambiguity issue. In my knowledge, class instance is different by the data members, but common (share) in executable code.
In my sample, IUnknown, IX and IY are all classes which do not have data members, they should share the common executable code. Could you explain in more details why compiler complaint ambiguity issue and what blocks compiler from type conversion?
regards,
George
|
|
|
|
|
Since C++ hasn't special syntax for interfaces, I think the compiler isn't allowed to make special assumptions on them. I mean the compiler probably behaves as it was dealing with standard classes (that can have data members), hence finds ambiguities on derivation path.
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]
|
|
|
|
|
Hi CPallini,
We can discuss in the situation of class other than interface.
Ambiguity means more than one different values could be selected. The different values in class is data members, not functions.
You can see there is no data members in IUnknown, IX and IY. Why there is ambiguity (I am not sure whether I have made myself understood about why in my context there is ambiguity)? I think the ambiguity occurs because of the data members are different.
regards,
George
|
|
|
|
|
George_George wrote: We can discuss in the situation of class other than interface.
Actually the OOP term to designate a C++ abstract class is interface .
George_George wrote: Ambiguity means more than one different values could be selected. The different values in class is data members, not functions.
I know that. But, as I suggested before, since C++ syntax has no special syntax to designate interfaces (i.e. abstract classes) then probably the compiler cannot make assumptions on them and remains stuck to the more general case, thus finding (inexisting) ambiguities on the derivation path.
However, there is another reason I missed before: suppose, for instance, both IX and IY classes override one IUnknown member, say AddRef , due to polymorphism, how can the compiler resolve between IX::AddRef or IY::AddRef if it cannot make assumptions on the abstract nature of IX and IY classes?
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 for your great reply, CPallini!
1.
CPallini wrote: know that. But, as I suggested before, since C++ syntax has no special syntax to designate interfaces (i.e. abstract classes) then probably the compiler cannot make assumptions on them and remains stuck to the more general case, thus finding (inexisting) ambiguities on the derivation path.
No matter whether they contain data member, right?
2.
CPallini wrote: how can the compiler resolve between IX::AddRef or IY::AddRef if it cannot make assumptions on the abstract nature of IX and IY classes?
I do not quite understand your statement above. Could you show some pseudo code please?
regards,
George
|
|
|
|
|
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
|
|
|
|