tags:

views:

72

answers:

1

I have a COM DLL (say, xyz.dll) coded in VC++. I want to create a calling EXE application (calling.exe) which will call the functions of the COM DLL (xyz.dll).

I followed the steps in the link http://www.codeproject.com/kb/DLL/XDllPt1.aspx. But I am not able to connect the DLL and EXE and hence not able to call the functions of the COM DLL. I am totally new to COM and VC++ programming. Can anyone kindly help me with.

I am using Visual Studio 2005.

These are the exact steps I followed--------

STEP 1: Created a solution having the DLL project (xyz.dll) project and a caller application Project (calling.exe) of template MFC Application (Dialog based). Made this calling.exe as the startup project..

STEP 2: Went to the properties by right clicking on the calling.exe Project in solution explorer. Configuration properties --> C/C++ --> General--> Additional Include Directives and added the path to the DLL Project..

Step 3: Again Right Click on the calling.exe application Project went to Properties--> Configuration properties --> Linker --> Input --> Additional Dependencies and added the path to the .Lib file for the built DLL Project.

STEP 4: *Right click on calling.exe application Project*, Properties --> Common Properties --> References --> Added reference to the DLL.

STEP 5: *Copied the xyz.dll file to the application project directory.*

STEP 6: My DLL has many header files and its corresponding source files. So, Added all the header files present in the DLL Project to my calling.exe application program. Within the OnInitDialog() function present in one of the .CPP program of the calling.exe application, I called the functions of DLL.

Just the statements

Cx objname; objname.func();

Here Cx is the name of the class in the DLL.

I did not do any changes with the configuration settings of the EXISTING DLL project because it is The DLL which is already prepared by an expert and I am writing just the calling applaction to call the functions present in this DLL.

THANKS IN ADVANCE.

+2  A: 

The instructions you've followed are for calling functions in an ordinary DLL, not a COM DLL. To access a COM DLL you need to go through COM.

You don't link to the DLL's lib file or include any headers, and you don't need to move the DLL.

First, make sure the DLL is registered by running regsvr32 on it.

regsvr32 "c:\..\..\xyz.dll" ; insert the correct path

Then add an #import directive to your project's stdafx.h, containing the path to the DLL.

#import "c:\..\..\xyz.dll" // insert the correct path

Right click stdafx.cpp in the file view and choose compile. This will generate the wrapper "smart pointer" classes you need to access your DLL. The smart pointer classes have the same names as the interfaces in your DLL, but with "Ptr" on the end.

Look at the file with a .tlh extension and the same name as your DLL in your Debug directory. It begins with a C++ namespace declaration. This is the namespace in which the objects you are going to create from the DLL reside.

Say the namespace is XYZ and you want to instantiate a Cx object, which exposes the Ix interface. You would do:

try {
    XYZ::IxPtr obj;
    obj.CreateInstance(__uuidof(XYZ::Cx));
    obj->func();
} catch (_com_error e) {
    printf("Error: %S\n", e.Description());
    printf("Error: %S\n", e.ErrorMessage());
}

You can then continue to use it just like an ordinary pointer. You don't delete it when you have finished with it though, it will be destroyed automatically when it goes out of scope.

Martin Broadhurst
Put your #import before all of the other headers in stdafx.h.
Martin Broadhurst
Hi martin Thank you very much for your kind help. I successfully called the functions of the DLL from my console VC++ application by following the steps given by you...
You're welcome. Accept my answer (click the tick next to it) if you're happy with it.
Martin Broadhurst
While debugging (using F11) the calling.exe application, when I stepped into the function call statement, I am getting an error in the header file "comip.h". The exact place where I am gettin the error is Interface* operator->() const { if (m_pInterface == NULL) { _com_issue_error(E_POINTER); } return m_pInterface; } The error is poppin a window as ----- There is no source code available for the current location. Do you want to see Disassembly. Can you kindly help..
Should I use CoInitialze(NULL) USES_CONVERSION etc.... ? My doubts may seem silly since I am totally new to COM programming. Kindly guide me. I dont know the reason I am not able to debug it and getting the error in "comip.h" header file. Thanks in advance...
You will need to call CoInitialize(NULL) if it's a console application, and CoUninitialize when you've finished. In an MFC App I think there's an AppWizard setting for COM support which does this. I'm not sure about USES_CONVERSION; it would depend what you are doing.
Martin Broadhurst
Make sure you check for errors with try...catch. You can get meaningful error messages from the exception thrown. I've added example error checking code to my answer.
Martin Broadhurst
Actually I have created a console application and calling the COM DLL functions because, earlier when I had created an MFC application, I was gettin the error, "WINDOWS.H already included. MFC apps must not #include <windows.h>". So, now I added COInitialize(NULL) to the begining of my code and COUninitialize() to the end of my calling application code, also I surrounded the code with try catch as said by you. but I am getting "Null" output for e.Description() and o/p as "I" for e.ErrorDescription. And still the error is in d same "comip.h" header file, at d stmnt I said in d above comment.
Interface* operator->() const { if (m_pInterface == NULL) { _com_issue_error(E_POINTER); } return m_pInterface; } This is the exact code snippet within the "comip.h" header file where I am gettin the error, when I step into the function call statemant during debugging (F11). Can you help me to debug this application successfully.
Are you declaring the Cx (or whatever) in the same scope as you are calling CoInitialize?
Martin Broadhurst
After doing the import stmnt and above settings said by you, when I typed "namespace name" (say, XYZ) and than :: the intellisense in VS prompted me with Cx (the class name in the DLL.tlh), Ix (The interface implemented by this class Cx), and IxPtr. So, I selected the IxPtr and created an object of the type IxPtr. I think I should have created an object of class "Cx" type right? But the smart class with suffix Ptr was only for the interface "Ix" as "IxPtr". And YES I am declaring both Smart class "IXPtr" and CoInitialize in the same function Main() of the calling.exe console appl.
When I drilled into the error I found out that, it is asking for the file, "comsupp.cpp" in the the path C://...../xyz.dll/obj/Debug directory. And its throwiing error that this comsupp.cpp file is not found. And I think tats the reason its throwing the error as " THERE IS NO SOURCE CODE AVAILABLE FOR THE CURRENT LOCATION" and prompting SHOW DISASSEMBLY".
inline HRESULT Ix:: funct1 ( const _variant_t This is the statement inside the xyz.tli file and when I am callin d function funct1(), the control is stoppin at the line HRESULT _hr = raw_setUser(varUser); in d above code snippet and hence I think, the function is not gettin called. Can I get the help to debug this please...
Yes Martin I followed as you guided. My code is building perfectly. But I am getting the above set of errors (Errors that I have listed in my previous comments) when I try to debug my application. Kindly can u help me with this.
I have explained the details of this problem in another question. Can u kindly refer this link http://stackoverflow.com/questions/4022340/not-able-to-call-the-functions-of-com-dll-from-a-vc-application. Can you kindly help. Your earlier answer was very much usefull but the function call statement is not getting executed. Plz look into the link..