|
That means it is a standard C/C++ DLL, not a COM Dll. You cannot add a reference to the DLL and use it directly like a COM component.
That means you'll have to use API style declarations to access whatever functions the dlls export. You'll also have to figure out how to translate all the unmanaged types into C# compatible types. I'd start looking for a OpenCV user group if I were you.
Robert
|
|
|
|
|
Hello Robert,
I appreciate your tip very much!
Thanks & Have a good weekend,
Khang
|
|
|
|
|
Hello
I want to write my COM object so that a C++ program can use it and a VB program can use it also. When I build my COM object using the wizard I get the IDispatch interface which means I can access my COM object using automation. My COM object has methods all of which return either S_OK or S_FALSE depending on what happens during the method call. My C++ program can get the results of a method call to my COM object to find out what went wrong if an error occurred. My VB program cannot do this.
What is the best solution to this problem?
Is there anywhere a guide as to how best write COM objects in C++ that are as language independent as possible but especially C++ and VB?
|
|
|
|
|
VB actually does receive the S_OK and S_FALSE values. It just processes them behind the scenes so you do not see them in VB.
When you are building the Com object in the wizard check the Support ISupportErrorInfo option and the VB client will be able to receive error information.
To fill in the error info you need to call the Error method in CComCoClass in your ATL component. It has various overloaded versions that allow you to fill in the error info you want to return.
Robert
|
|
|
|
|
Thank you for the reply. So it processes them behind the scenes? Can I tell if S_OK or S_FALSE was returned then? Is S_OK equal to 0 in VB? What type does it return a string or an integer? I tried it with an integer and it did not work or if it returns S_FALSE will it raise an exception in VB?
|
|
|
|
|
Anonymous wrote:
Can I tell if S_OK or S_FALSE was returned then? Is S_OK equal to 0 in VB? What type does it return a string or an integer? I tried it with an integer and it did not work or if it returns S_FALSE will it raise an exception in VB?
Sorry, it's been a long time since I looked at this stuff. I'll try to explain as much as I can remember.
1) Your attempt to return an integer failed because VB requires all COM calls to return an HRESULT.
2) You cannot ever get the original value of an HRESULT in VB because the runtime pre-processes it behind the scenes. You cannot tell if S_OK was returned or if S_FALSE was returned, because you can never get directly at the actual HRESULT returned.
3) Returning a S_FALSE will not raise an error in VB because S_FALSE is actually a success code, not an error code. The first thing VB does when it processes the HRESULT behind the scenes is strip out the low word and check it for a severity level. An S_ code is always considered successful based on the low word, so VB just discards the rest and keeps going. In order for an error to be raised in VB the severity level of the low word must be an error level. So if your method returns E_FAIL, VB will look at the low word of the HRESULT, see it is an error level severity and go from there.
4) What happens in VB if you return an E_ HRESULT depends on how you've written your COM component:
If you support rich error information:
Your COM object must first call SetErrorInfo and fill the EXCEPINFO parameters. (If you are using ATL you can just call "Error(...)" and it provides overloaded constructors that will do all the work for you).
Then your COM object returns an E_ level HRESULT.
VB catches the E_ severity code level and will query your COM object to see if it supports the ISupportErrorInfo interface. Since in this case you do, it will call GetErrorInfo to get the EXCEPINFO structure.
If you do not support rich error information:
Your COM object simply returns an E_ level HRESULT.
VB catches the E_ severity code level and will query your COM object to see if it supports the ISupportErrorInfo interface. Since in this case you don't, VB does not attemnpt to call GetErrorInfo.
Since rich error info is not supported, VB tries to process the high word of the E_ HRESULT and translate it into a VB friendly standard error and standard VB message.
For example, suppose VB calls a method on your COM object and the method returns E_OUTOFMEMORY. The VB runtime strips out the low word, sees it is an error, looks at the high word and maps the error to the standard VB "Error 7 Out of Memory".
Finally,
The only ways to return an actual value to VB if you do not want to raise an error is by a [retval] parameter or by a ByRef [in, out] parameter. Of course all COM calls are functions - they return HRESULTS. But here is how VB interprets COM mmethods:
COM:
HRESULT MySub([in] long mylong);
VB:
Sub MySub(ByVal mylong As Long)
---------------------------------
COM:
HRESULT MySubByRef([in, out] long mylong);
VB:
Sub MySubByRef(ByRef mylong As Long)
----------------------------------
COM:
HRESULT MyFunction([in] long mylong, [out, retval] bool* p_boolRetVal);
VB:
Function MyFunction(ByVal mylong As Long) As Boolean
In all cases you never can get access to the HRESULT values in VB.
Hope this helps ...
Robert
|
|
|
|
|
Sorry, this stuff is complicated.
I have to make a correction to the above statements.
I said you could never get the HRESULT. That is not exactly true.
You can never get S_ level HRESULTS because VB discards them.
You can get E_ level HRESULTs in one of two ways:
If your COM object does not support rich error info, you could reconstruct the original E_ value if you know how to map the VB Err.Number back to an oreiginal E HRESULT. For example E_OUTOFMEMORY returns Error 7 in VB which can be mapped back to 8007000E.
If your COM object supports rich error info then the Err.Number property in VB will correspond exactly to the original HRESULT, i.e if you look at Hex(Err.Number) in VB the value will be 8007000E for E_OUTOFMEMORY.
But for what you were trying to do, i.e get an S_OK or S_FALSE in VB, the answer is still no, you cannot do it.
Robert
|
|
|
|
|
Thank you for your detailed explanation.
My problem is that I have written my COM objects to all return SOK or S_FALSE so that a client can easily decide if a call failed or not. My COM component native language is C++ and this is perfect for C++ clients.
Can I get this absolutely right then? If I want to support VB clients as well, what I really need to do is to provide an output parameter that both VB and C++ clients can check, and I can forget about using S_OK and S_FALSE if my clients maybe VB.
One more thing and this is something I have not understood before I think. S_FALSE is not an error code it is a boolean return value so returning E_FAIL would be the way of informing VB clients that it has failed. I have always written in COM to return S_OK on success and I then expect my clients to just test for S_OK. Now I see that VB clients cannot do this. They cannot test for S_OK, they can't have a value returned but can only test for an error for example E_FAIL.
Thank you for your help with this but I am having to relearn COM and recode
|
|
|
|
|
Anonymous wrote:
If I want to support VB clients as well, what I really need to do is to provide an output parameter that both VB and C++ clients can check, and I can forget about using S_OK and S_FALSE if my clients maybe VB.
Yes you can provide an output parameter that indicates if the method call succeeded or failed, but VB will not distinguish between S_OK and S_FALSE.
Anonymous wrote:
Now I see that VB clients cannot do this. They cannot test for S_OK, they can't have a value returned but can only test for an error for example E_FAIL.
They can test for an error only on an E_ code. Yes.
They can also have a value returned as a [retval] parameter.
So you have two choices. You can return a parameter, or you can return an E_ code if the function call fails.
I would use an E_ code.
Robert
|
|
|
|
|
hello everybody!
i habe an urgent problem!
there are 2 components i developed in Visual Studio 6 with ATL.
i used the standard wizard to create the DLL´s.
Short explaination of the 2 components:
1. Modul: Search: this dll makes a search against a data-file. it has got interface can used by the most common program languages.
2. Modul: SearchOverXML(using MSXML 4 SP2): this dll receive the parameters used for Modul 1 from a Client, receive a Object, which contains the Result from Modul 1 and the Modul 2 will write the Result-Data in a specific XML-Structur to the Client.
and now my problem. if i call Modul 2 10000 times from a client, the memory is rising and rising and if memory is out the application crashes.
i cleanup all references to MSXML and if i want to call the Release-Method on the Modul 1 Object (i forgot it at first) the Client crashes and the Memory-Leak is still there.
if i call modul 1 only, i have got no problem!
so, i dont know what to do know. maybe the implementation of Modul 2 is wrong. Has somebody a Code Example how to call a ATL Server from a other ATL Server?
thanks for help
best regards
andreas
|
|
|
|
|
Hi
I´m working on a Single Sign On system using a BHO in VC 6.0
I would like to capture the mouse clicks, and using elementFromPoint() obtain a element name, so later i could complete the data.
I think i should use put_onclick() to override the default mouse handler, but the documentation is really bad and i dont understand how to use it.
It says that the parameter is a pointer to an IDispatch interface, that implements a default mouse handler, but...
Should i create a new interfase with a method to handle the mouse events?
How should this method be named?
I would really apreciate any help
Thanks in advance
Sebastian
|
|
|
|
|
Hi.
I am creating the Outlook Object Library 11.0's application object in C++ and calling its CreateDispatch method in an MFC Regular DLL's exproted function. When i call that function from a windows application it is working fine, but when that function is called from a windows service the CreateDispatch function of the application object fails. Please tell me what is this problem. The windows service is configuered to run with a user of windows NT domain.
Here is the code
if(objApplication.CreateDispatch("{0006F03A-0000-0000-C000-000000000046}"))
{
objNameSpace = objApplication.GetNamespace("MAPI");
if(objNameSpace!=NULL)
{
isLoggedIn=TRUE;
return TRUE;
}
}
isLoggedIn=FALSE;
return FALSE;
Common Man
|
|
|
|
|
Hello, I have an swf embedded into an MFC dialog window. MFC is staically linked, Swf embed=true.
The swf appears to be compiled into the exe.
My question: Is there ANY way that someone could extract the swf from the exe?
It is very important that this is impossible, as the swf can not be unprotected.
|
|
|
|
|
can you help me the way to combine DLL and EXE files into 1 single file ? and the way to group DLL files into 1 single DLL files. I'm using .NET language.
thanks
|
|
|
|
|
Hi all,
I have written an application in which I embed powerpoint in my application using COM. But the problem is I'm getting some version dependencies in office...I'm facing some problem when I am running with different powerpoint(MsOffice) versions(Office 98,2000 or XP).
How to know to which version of powerpoint I'm linking so that I can make my application version inependent...
Plz help,
Regards,
sam.
|
|
|
|
|
Well, you have an obvious solution - write a different version application for each version of Powerpoint.
There is a more elegant approach. This is pretty complicated to even explain. You'll have to be pretty strong on COM to be able to program this effectively.
Basically since your application needs to be compatible with different versions of the PowerPoint object library, you must decouple the application from any direct reference to the object library itself. That means you need to code your application against an abstract interface definition instead of the Powerpoint library itself.
You also have to create implementation DLLs for each version of PowerPoint you support. These have to contain concrete impementation classes and be compiled against the correct version of the Powerpoint object library.
Finally, you have to create a Class Factory that determines which version of Powerpoint is installed, and registers the correct implementation DLL at runtime, then returns the concrete Powerpoint class from the appropriate DLL that implements the abstract interface definition.
You install all concrete implementation DLLs on the target machine but you do not register any of them, because only the one that matches the current version of Powerpoint on the machine will register correctly anyway.
Since the Class Factory determines at runtime which version is currently installed, and actually registers the correct concrete implmentation DLL and then returns the implementation class, if your user decides to upgrade from example Office 98 to Office 2000, then the class factory will recognize that and automatically upgrade the concrete implmentation DLL.
Like I said, elegant, but not simple.
Robert
|
|
|
|
|
Hi Robert,
Thanx a lot for ur suggestion, however ,I'm quite an amateur in COM to try out all this.....
Still I'll give it a try...
1 more question:- I want to call some COM interface functions in a separate thread.. How to do that? I called CoInitialize() and then tried calling inside the new thread...but it didn't work out...
Plz help.....
Thanks & regards,
sam.
|
|
|
|
|
Hi,
Is it possible to remove icons in the system tray, without stopping the process Ideally the function would take the process name and remove the icon. I know it can be done as I've seen tools which do it. Ideally through VBS but C++ would do as well.
I've searched plenty via Google and all I can find are articles on how to add icons
Thanks
|
|
|
|
|
no the systray only allows the process that registers itself to remove itself.
You can kill the explorer process (which is not a good option) to remove the element.
you can try to hook into the explorer process to determine where the registration section for the tray is but you would need to know what your looking for. Again is not a good option
|
|
|
|
|
I wrote a com object with ATL, it has a test function, which declared like "HRESULT test([in]byte* aaa);" ; I wrote the following code in a html file, want to call test function, but always get error message "type not match". Who can tell me is it possible to call test using VBScript and how to .
my script code:
Dim MyObj
Set MyObj = CreateObject("Test.Test")
Dim data(5)
data(0) = CByte(97)
data(1) = CByte(97)
data(2) = CByte(97)
data(3) = CByte(97)
data(4) = CByte(97)
data(5) = CByte(97)
MyObj.test data
|
|
|
|
|
VBScript is an untyped language, or more correctly all types in VBScript are VARIANT.
The problem is not in your VBScript, it is in your ATL method definition. To pass an array of any type into an ATL COM object from VBScript, you have to make several changes:
1) The parameter must be declared as [in, out] to force it to be passed ByRef instead of ByVal.
2) The parameter must be declared as a VARIANT* type.
3) You have to write additional code in the ATL function to convert the VARIANT* array into a byte array.
So, your new function definition must be:
"HRESULT test([in, out] VARIANT* aaa);"
Once you have passed the array into the ATL COM object you need to access it as a SAFEARRAY and retrieve the values as VARIANTS then cast them to bytes.
For more info see:
http://support.microsoft.com/kb/218454/EN-US/[^]
Robert
|
|
|
|
|
Hi,
I've got a COM component that needs to read/write browser cookies (the component is on the client machine and does not run in the context of an IE Toolbar or the like). Are there any API's available to do this or will I need to roll my own?
Thanks in advance,
-Robin
|
|
|
|
|
You probably want InternetGetCookie[Ex] and InternetSetCookie[Ex].
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
That does the trick, thanks!
|
|
|
|
|
RCox wrote:
does the trick
sdgsdfgdgdfgdfgdfgdgd
|
|
|
|