views:

1447

answers:

4

Hi,

Consider me a novice to windows environment and COM programming.

I have to automate an application (CANoe) access. CANoe exposes itself as a COM server and provides CANoe.h , CANoe_i.c and CANoe.tlb files. Can anyone specify how to write a C++ client, for accessing the object, functions of the application.

Also, please specify how to access the code present in tlb file from C++.

Thanks in advance.

+1  A: 

Use import directive to import the .tlb file - this will give you a C++ equivalent of the interfaces exposed by the COM component.

You will also need to register the COM component to the registry (run regsvr32 on the .dll file of the component). After that you can call CoCreateInstance() (or _com_ptr_t::CreateInstance() as it is usually more convenient) to create an instance of the class that implements the interface. You can then call methods of the interface - it will work almost the same way as if it was a plain C++ interface and class.

sharptooth
Thanks to all for quick response.I am not having the DLL file for the application, so will prefer this approach.Getting following compilation errors, after #import "CANoe.tlb" in my source file.- unknown character '0x1'- syntax error : missing ';' before identifier 'A'- missing type specifier - int assumed. Note: C++ does not support default-int- '{' : missing function header (old-style formal list?)Please suggest, if I am missing some step.Is there a way to verify the .tlb file contents and resolve these errors.Thanks in advance
I suggest you try to resolve it and if you don't manage just ask a separate question providing enough details.
sharptooth
+1  A: 

Visual studio has a lot of built in support for importing type libraries into your C++ project and using the objects thus defined. For example, you can use the #import directive:

#import "CANoe.tlb"

This will import the type library, and convert it to header files and implementation files - also it will cause the implementation files to be built with your project and the header files to be included, so this is lots of magic stuff right there.

Then, you get a whole lot of typedefs for smart pointer wrappers for the types and objects defined in the type library. For example, if there was a CoClass called Application which implemented the interface IApplication, you could do this:

ApplicationPtr app(__uuidof(Application));

This would cause at run time, the coclass application to be created and bound to the variable app, and you can call on it like so:

app->DoSomeCoolStuff();

Error handling is done by checking the result of COM calls, and throwing the appropriate _com_error exception as necessary so this implies you need to write exception safely.

1800 INFORMATION
A: 

The easier way is to include both .h and _i.c project in your .cpp file using #include statements.

Since you haven't been given the dll and only tlb is provided, you can register the tlb using regtlibv12.exe which is a part of visual studio (this is the VS2005 version). By registering tlb, appropriate entries will be made in the registry and then you can use the COM library functionality as you need.

EDIT: BTW, you need DLL anyway to instantiate the COM Component successfully.

To create an interface pointer, one of the safer ways is to use CComPTR like:


CComPtr myPtr;
myPtr.CoCreateInstance(__uuidof("ClassNamehere"));
myPtr->Method(....);


Aamir
If he doesn't have the DLL he will be unable to instantiate the component and debug his client program.
sharptooth
Yes, but it is quite possible that the tlb file only contains interface definitions and needs to be registered separately. You are right about DLL though that he should have it to instantiate the component.
Aamir
Well, you're right about separate tlb registration being possible. But it's a last resort practice usually used when the COM component has incomplete COM support and doesn't support DllRegisterServer and DllGetClassObject.
sharptooth
This can be done at places where you want to keep Interface Definitions separate from their implementations. e.g., an Interface that has to be implemented differently in multiple COM Components, such an interface can be moved out and a separate tlb can be created for that interface. All the components that would implement that interface will simply import that tlb and go on from there.
Aamir
A: 

slight mistake in that example

if the interface was IApplication then you'd be doing this:

IApplicationPtr app(__uuidof(Application));

don't forget to call CoInitialize() before you do this. and of course, CoUninitialize() when you exit.

Olipro