|
The Problem
----------------------
I was just compiling some C++ COM code just now on a machine (not my own).
The same code compiled well on my machine but could not succeed on this other machine.
The compilation error is printed below :
D:\limbl\Develope\SMPT_FrameWorks\Devt\Wrappers\COM\WebServiceServers\FacialRecognitionWebService\FRWebService.cpp(304) : error C2668: 'InlineIsEqualGUID' : ambiguous call to overloaded function
STDMETHODIMP CFRWebService::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* arr[] =
{
&IID_IFRWebService
};
for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
if (InlineIsEqualGUID(*arr[i],riid)) // <-- problem is reported here.
return S_OK;
}
return S_FALSE;
}
How to Resolve The Problem
-----------------------------------------------
The MSDN documentation could not help me much and I experimented with some Visual C++ settings. I eventually resolved the problem by resetting the Tools|Options|Directories settings for "Include files".
I found that in the Tools|Options|Directories settings for "Include files", if the Microsoft SDK include folder (e.g. C:\PROGRAM FILES\MICROSOFT SDK\INCLUDE) is set to the top of the list or is above the Visual C++ include folder (e.g. C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\INCLUDE), the problem will occur.
I now set the Microsoft SDK include folder to below the Visual C++ include folder. The compilation problem is now resolved.
I currently haven't the time to find out the root cause of the problem. If anyone finds out, please share with all of us.
|
|
|
|
|
Lim Bio Liong wrote:
if (InlineIsEqualGUID(*arr[i],riid)) // <-- problem is reported here.
To resolve problem we can call global InlineIsEqualGUID like this way
(::InlineIsEqualGUID(*arr[i],riid))
this will compile code without problem!
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
cheers,
Alok Gupta
|
|
|
|
|
Hello Alok,
Thanks for the tip, Alok. I'll give it a try.
Best Regards,
Bio.
|
|
|
|
|
Hello Alok,
I had an occassion to use your solution to this problem today. It worked great
Thanks v much, buddy !
Best Regards,
Bio.
|
|
|
|
|
Lim Bio Liong wrote: Thanks v much, buddy !
Mention not, Sir!
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
|
|
|
|
|
Some recommended reading on a subject close to our hearts :
Debugging Release Mode Problems
Web link :
http://www.codeproject.com/debug/releasemode.asp
|
|
|
|
|
For every SOAP call to a Web Service method, SOAP and IIS will create the COM Object that implements the method, invoke the appropriate Object Method, and then destroy the COM Object.
|
|
|
|
|
Check out this web site :
http://www.ddevel.com/DrCOM/DrCOMMonitor.asp
This site features a cool COM Spying utility called DrCOM. It looks potentially cool and useful. Try downloading their trial DrCOM software.
|
|
|
|
|
Recently, Wee Fong and I had the pleasure of working with C# and lots of COM Interopt stuff. We also had the chance to delve quite deeply into the area of COM Interface Marshalling. The following are some useful pointers that we learnt from our forays into the internal guts of COM Marshalling :
1. COM objects that are Apartment-Threaded-Model based can only have its interface methods invoked directly from the same thread that created the COM Object. The thread that created the COM Object is known as the owning thread.
2. To use the interface methods of an ATM COM Object in a thread different from the owning thread, i.e. the one in which the object was created, the interface pointer of the object must be marshalled to the target thread.
3. The owning thread that created the COM Object must be also be a User-Interface thread. That is, it must contain a message loop like the following :
MSG msg;
// Dispatch all windows messages in queue.
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage (&msg);
DispatchMessage(&msg);
}
4. This is because when an ATM COM Interface method is invoked from a non-owning thread, COM serializes the method call by inserting a Windows Message into the owning thread. This is the simple way in which interface method calls are serialized.
5. Serialization is COM's way of ensuring that the internal state (properties and other internal data) of a COM Object is not corrupted by multiple threads.
6. Please note that -it is- possible to create and use COM Objects (even ATM based) in a thread that does not have any message loop (case in point : console apps). However, in this case, you will not be able to share COM Interfaces across multiple threads.
7. How do we determine the Thread Model of a COM Object ?
Look up the registry entry of the CLSID of the COM Object, e.g. :
HKEY_CLASSES_ROOT\CLSID\{82124FF1-0610-4607-ACFE-8C16E30AF280}
Here, there will be a "InprocServer32" subkey and here you will find a string value named "ThreadingModel". If the string value is : "Apartment", the COM Object is an Apartment-Threaded Model COM Object. But of course, if you had written the COM Object yourself, you will know what Threading Model you had used.
(continued in part 2)
|
|
|
|
|
8. To marshall an interface pointer from the owning thread to a another thread, use the CoMarshalInterThreadInterfaceInStream() and the CoGetInterfaceAndReleaseStream() APIs.
9. Note that marshalling an interface pointer is just one-half of the game. The other half, which in many ways is more challenging and interesting, involves the marshalling of the PARAMETERS of the interface methods.
10. If you make your interface dual or IDispatch-based, the marshalling of the methods' parameters is performed completely automatically for you curtesy of COM.
11. This is logical because dual and IDispatch interfaces can use only OLE Automation-Compatible Types for parameters (e.g. VARIANTs, BSTRs, etc). COM has already prepared itself to marshall these types of parameters.
12. Non-dual and non-IDispatch based interfaces (aka Custom Interfaces) must provide their own custom marshalling. Proxy and stub DLLs must be created for this purpose.
13. Note also that dual and IDispatch based interfaces also use a proxy/stub DLL to perform parameter marshalling. This proxy/stub DLL is the famous oleaut32.dll (read it as OLE AUTomation 32 DLL).
14. To determine or confirm if your interface uses oleaut32.dll to marshall parameters, look up the registry entry of your Interface, e.g. :
HKEY_CLASSES_ROOT\Interface\{66AD7066-C70F-4136-A108-71DC34F3305C}
Here you will find a "ProxyStubClsid32" subkey. It should have a "Default" string value. The value is the CLSID of the object that implements the marshalling functionality of your interface.
15. Look up the registry entry for this CLSID and you will see the in-proc server DLL of the marshalling object. If your interface is dual or IDispatch based, the CLSID should be :
{00020424-0000-0000-C000-000000000046}
If you look up this CLSID entry in the registry, i.e. :
HKEY_CLASSES_ROOT\CLSID\{00020424-0000-0000-C000-000000000046}
you will find the following information :
15.1 The default string value for this CLSID is "PSOAInterface" (read this as Proxy Stub OLE Automation Interface). PSOAInterface is the "universal marshaler" that creates in-memory COM stub/proxy pairs based on type library information. PSOAInterface is oleaut32's tool that enables VB to do "somewhat native" COM marshaling by mimicking the functionality of "midl /Oicf" on-the-fly. PSOAInterface builds and caches native COM proxies based on type libraries. The downside of PSOAInterface is that it requires interfaces that use it to be OLE-Automation compatible, that is, it must return HRESULTs and its parameters must be OLE-Automation types, since that is what it was built for and that's the set of types that COM type libraries can express.
15.2 There is an "InprocServer32" subkey. In this subkey, you will find that the default string value is "oleaut32.dll".
We hope the above information will be useful to all. There's still quite alot of information to share with all on this same topic. We'll be updating this Knowledge Sharing Article with a Part 2 soon.
|
|
|
|
|
Understand Common Virus Attacks Before They Strike to Better Protect Your Apps
by Jason Fisher
The web address of this article is :
http://msdn.microsoft.com/msdnmag/issues/03/05/VirusHunting/default.aspx
This article presents information on some of the techniques viruses use to launch themselves and get into your system.
|
|
|
|
|
1. User A accesses the Web Application.
1.1 The Web Application Starts up (System.Web.HttpAplication.Application_Start() event is fired).
1.2 A new Session is started (System.Web.HttpAplication.Session_Start() event is fired).
2. User B accesses the Web Application.
2.1 The web application is already started up.
2.2 A new Session is started (System.Web.HttpAplication.Session_Start() event is fired).
3. The web application will only end after both User A and User B sessions end.
3.1 When a session ends, System.Web.HttpAplication.Session_End() event is fired.
3.2 When a web application ends, System.Web.HttpAplication.Application_End() event is fired.
|
|
|
|
|
The Global.asax file captures the start and end of both application and user sessions.
1. Application - when the internet application is first run by a user. Happens only once during an entire APPLICATION session.
2. Session - when a user requests for a page within an application. This happens everytime a new user accesses web pages of an application.
Definition of Session State :
The current value of all the controls and variables for the current user in the current session.
Note : values stored in Session variables are unique for each user session.
|
|
|
|
|
Microsoft ASP.NET solves the HTTP Stateless and CGI Performance Problems through :
1. Application Management.
2. Session Management.
3. Viewstate.
4. Model View Controller (Code behind) Architecture.
5. Automatic Memory Allocation System (Garbage Collection).
|
|
|
|
|
Microsoft Classic ASP solves the HTTP Statelessness Problem through :
1. Application Management.
2. Session Management.
|
|
|
|
|
1. HTTP : lack of session management (due to statelessness).
1.1 HTTP is usch that web applications are not able to "remember" a user's past status and operations.
1.2 It does not provide any means for a web app to clearly mark the start and end of a client user's engagement.
1.3 It does not provide any means for a web app to clearly mark the start and end of the entire application.
2. CGI : low in performance.
2.1 CGI does not operate in Multi-tasking and multi-threading environment.
2.2 It is difficult to support the programming of reusable codes.
|
|
|
|
|
This can be done by setting the "AutoPostBack" property of a Web Server Control to TRUE.
This is known as POSTBACK.
|
|
|
|
|
1. Use a button of type "submit". Embed this button inside a <form></form> tag in the web page's HTML.
2. Call the submit() function inside javascript, e.g. :
function SubmitForm
{
this.Form.submit;
}
|
|
|
|
|
Also note that the form tag must have the appropriate action attribute, e.g. :
<form name="MyForm" action="www.somesite.com/somepage.asp">
...
</form>
|
|
|
|
|
WebServiceObject wso = new WebServiceObject();
AsyncCallback cb = new AsyncCallback(MethodCallback);
try
{
wso.BegindoAsyncFunction
(
some_param_1,
some_param_2,
cb, // 2nd last parameter is always the AsuncCallback object.
(object)wso // This object (whatever it is)
); // is returned in IAsyncResult.AsyncState in
// callback function.
}
catch(SoapException se)
{
...
}
private void MethodCallback(IAsyncResult ar)
{
WebServiceObject wso = (WebServiceObject)ar.AsyncState;
string strRetVal = wso.EnddoAsyncFunction(ar);
...
}
|
|
|
|
|
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
|
|
|
|
|
C# Code :
byte[] byImageBytes = GetImageBytesFromSomewhere();
MemoryStream ms = new MemoryStream(byImageBytes);
pictureBox_Image.Image = Image.FromStream(ms);
|
|
|
|
|
<html>
<body>
<form action="http://localhost/MyWebService/MyWebService.asmx/MyMethod" method="POST">
<input name="a"></input>
<input name="b"></input>
<input type="submit" value="Enter"> </input>
</form>
</body>
</html>
|
|
|
|
|
1. To provide a common way of packaging message data.
2. To define encoding rules for serialization and deserialization of data transmission.
3. To provide a model that can be used to implement RPC operations using SOAP.
|
|
|
|
|
Misconception #1 - SOAP is nothing more than a protocol for RPC over HTTP.
* No, this is just one implementation of SOAP.
Misconception #2 - SOAP specification requires the use of HTTP.
* No, SOAP can be used with any protocol.
* Microsoft and others have implemented SOAP messages over SMTP.
Misconception #3 - SOAP works on HTTP request/response conversation.
* No, that supports the transmission of XML data from sender to receiver.
|
|
|
|