tags:

views:

149

answers:

3

Hi all.

I wish to use a COM dll in my C++ library. The way I figured going about it, is to #import the dll's .tlb file, which I did :

#import "mycom.tlb" no_namespace

The problem is , I don't quite know where to place this declaration. should it be inside the H file or the CPP file? or maybe the stdafx.h file? I tried placing it in the .cpp file , just for testing.

in the H file I have this member declared :

ILogicSecuredPtr m_pbLogic;

(where ILogicSecured is the interface I want to work with in my COM dll)

Then I added this in the constructor to instantiate the interface :

CoInitialize(NULL);
m_pbLogic(__uuidof(LogicSecured)); 

(where LogicSecured is the name of the object that implements the interface)

In the destructor I added :

CoUninitialize();

This won't compile however, no matter where I try to place the #import declaration. it just doesn't recognize the ILogicSecured object. I get this error in the H file :

Error   2   error C2146: syntax error : missing ';' before identifier 'm_pbLogic'

I should also mention that when I F12 (in Visual Studio) on the ILogicSecuredPtr declaration, it takes me to the tlh file just fine. So I know it recognizes it.

What am I doing wrong here?

Thanks alot. Roey

+2  A: 

The problem is that when the compiler parses the .h file it has not seen the #import yet. Since your project is small your best bet is to put #import into stdafx.h.

When you press F12 Visual Studio uses Intellisence database information that is formed parsing all the sources in order that might be different from the compilation order. So it's quite typical to have Intellisence know where something is declared and the compiler to not compile it at the same time.

sharptooth
Can I thicken the plot a bit?If I try adding the #import into the stdafx.h file, the m_pbLogic(__uuidof(LogicSecured));piece of code does not compile, saying Error 18 error C2064: term does not evaluate to a function taking 1 arguments
Roey
That's right - you try to call the member variable constructor inside the constructor body - this is not allowed. You should use CreateInstance() method of the IWhateverPtr instead.
sharptooth
Thanks for the quick reply.Can you please provide a mock example of how to call CreateInstance in my situation? and where to place it?Thanks
Roey
call m_pbLogic.CreateInstance( __uuidof(LogicSecured) ) instead of trying to call m_pbLogic(...) - it will return an HRESULT - check it with FAILED() macro - if the call failed react accordingly - thrown an exception or something.
sharptooth
Thanks. Just one more thing, in my .h file I define a member as : ILogicSecuredPtr m_pbLogic;And in the cpp file where I try to do as you said, it says that m_pbLogic is undefined, and I get errors in the .h file as well.Can't I define a IWhateverPtr as a member in a .h file??
Roey
Have you included the header into the cpp file?
sharptooth
+1  A: 

What happens if you import a dll or tlb file is that the preprocessor generates a tlh and a tli file. If the tlb is stable you could also generate the two files and include the tlh header as if its a normal header.

So the answer is put the #import where you would put the header because it is converted into an include of the tlh file.

I use it in the following way to make myself independent of the location of the MSADO15.dll and added the tlh file to my subversion.

#ifndef __ADO__H
#define __ADO__H

#ifdef REBUILD_ADO_HEADER
#import "C:\Programme\Gemeinsame Dateien\system\ado\MSADO15.DLL" rename_namespace("MyAdoNamespace") rename("EOF","EndOfFile")
#else // REBUILD_ADO_HEADER
#include "MSADO15.tlh"
#endif // REBUILD_ADO_HEADER

// Define ADO Namespace as global
using namespace MyAdoNamespace;

#endif // __ADO__H
Totonga
A: 

In addition to the compile issues you are having, there are other problems with this design.

Generally, C++ libraries should not initialize COM on threads that it does not create. This can cause some nasty, hard to debug side effects. Consider updating the interface spec for your library to indicate that use of certain methods or objects require that COM be initialized. You should also specify the threading model required (STA, Free).

That said - the other thing you need to watch out for is calling CoUnitialize() before your smart pointer goes out of scope. This can also cause some hard to debug side-effects. If you're calling CoUnitialize() in the destructor of an object that contains a COM smart pointer, you'll need to explicitly release and detach the pointer prior to invoking CoUnitialize().

Have fun!

BukesRos