views:

495

answers:

4

Hi what's wrong with my code I am trying to register the class in registry in the following way but while I am debugging it shows that class is not registered and application crashes.

What is wrong in this code please Help me.

Test::IDiscover *pICalc = NULL;
HRESULT hRes=CoCreateInstance(Test::CLSID_SqlClass, NULL, 
  CLSCTX_INPROC_SERVER,Test::IID_IDiscover, reinterpret_cast<void**> (&pICalc)); 
if(hres<0) 
   cout<<"register failure"<<endl;
else
   cout<<"register success"<<endl;  // and i am not free the memory any where...

And I also tried like:

IDiscoverPtr pt(__uuid(SqlClass));
HRESULT hRes=CoCreateInstance(Test::CLSID_SqlClass, NULL, 
  CLSCTX_INPROC_SERVER,Test::IID_IDiscover, reinterpret_cast<void**> (&pICalc));
if(hres<0)
   cout<<"register failure"<<endl;
else
   cout<<"register success"<<endl;

If I do like this when I debugging this at

IDiscoverPtr pt__uuid(SqlClass));

The debugging goes to this function and shows COM error internally.

+1  A: 

Where is IDiscover interface defined? You need to register that particular DLL/EXE in which you have implemented this interface. To give you a hint, this will be the DLL in which you have a class named SqlClass. That will most probably be a Com DLL. Register that DLL using regsvr32 on command line.

Something like:

regsvr32 "MyDllFullPath.dll"

To further know, what is the exact error, tell us that what is exactly the value of hres. I am guessing that it is a numeric value which translates to Class Not Registered error.

Aamir
I already register that Dll using RegAsm.exe and generates the tlb file and importing that tlb file in c++ program from where i am using the above code.
Cute
OK, Things are getting interesting here. You have used RegAsm which means that your DLL is a .NET DLL, right? If yes, have you applied ComVisible(True) attributes to your classes and interfaces?
Aamir
@Cute: Did you use the /codebase switch when invoking regasm.exe?
sharptooth
Yes i used like this RegAsm.exe Test.dll /tlb:Test.tlb /codebase
Cute
+1  A: 

You are trying to create an instance of a COM class called SqlClass. You are not actually trying to register that COM class. To register the COM class, you would need to do

regsvr32 SqlClass.dll if your COM class is inprocess server

sqlclass.exe /regserver if your COM class is a out-of-process server.

The fact that you are using COM smart pointers tells me that your SqlClass lies in a DLL and you are using #import to refer to it. So use regsvr32 SqlClass.dll

An additional aspect is that always use the macros SUCCEEDED or FAILED to check the hresult return value of COM calls.

Modicom
A: 

Since you say that you have already registered the DLL using regasm.exe, check if the registration was done properly by using oleview.exe. Go to "All Objects" node in the left tree view and find if you SqlClass component is present.

I am not able to see the CoInitialize(NULL) call in your code. Are you calling CoInitialize(NULL) before calling CoCreateInstance?

Also can you please specify the COM error code?

Modicom
I am calling CoInitialize(NULL) before CoCreateInstance.
Cute
Can you please specify the COM error code?
Modicom
A: 

When registering .NET assemblies exposed to COM you use regasm.exe tool. It's important to not forget the /codebase command-line switch. Without this switch regasm will only put the name of the DLL into the registry, not the full path to it and when the consumer (your application) tries to call CoCreateInstance() COM will not be able to find out where the DLL actually resides.

sharptooth