Solved

ATL COM dll refuses to implicitly link with MFC dll

Posted on 2008-10-28
11
442 Views
Last Modified: 2013-11-20
None of the implicit linking methods work in this situation.
I have assembled a small sample solution that I desperately need an expert to look at.
The projects are Device, DevWrap and TestBench and are compiled under VC6.
The header file BioDevice declares the links.
The DevWrapper.cpp file requires the linking.
See CDevWrapper::CloseDevice() where the problem has been commented out.
 Urgent attention to this problem would be most appreciated.
I am expert at MFC but raw on ATL.
The object of the exercise was originally to wrap a MFC dll with a ATL COM wrapper so that the COM result could be used universally.
This site does not alow my zip components. Could I email this to a willing expert?
#include "stdafx.h"

#include "BioDevice.h"

#include "DevWrap.h"

#include "DevWrapper.h"
 

/////////////////////////////////////////////////////////////////////////////

// CDevWrapper
 

STDMETHODIMP CDevWrapper::CloseDevice(LONG* lngRetVal)

{

	int iRet = -1;

//	CDeviceApp * pDev;

//	pDev = new CDeviceApp();

//	iRet = dllClose();

	*lngRetVal = (long)iRet;

	return S_OK;

}

Open in new window

0
Comment
Question by:softbee
11 Comments
 
LVL 19

Expert Comment

by:mrwad99
ID: 22820014
Upload the file to http://www.yousendit.com/ (enter bogus mail addresses, that doesn't matter) and post the link it gives you here.
0
 
LVL 11

Expert Comment

by:alexcohn
ID: 22820016
Few technical issues first:

Are you still working with VC2003? It's not clear from your post.

To the best of my knowledge, you can "Attach files" of up to 5MB, including ZIP (other extensions are bmp doc gif jpeg jpg log mdb pdf png txt xls). You seem to need "scripts enabled" in your browser to upload files.

It is hard to understand what problem you have with the attached code: LNK2019 again?
0
 
LVL 2

Author Comment

by:softbee
ID: 22820111
I built a complete sample in VC6 since the original mfc dll was built using vc6 and it will not migrate to VS2003.
And yes, the problem stays the same, but is now easier to see, since all the other clutter has been removed.
I get the feeling that the ATL wrapper needs MFC support, but for the life of me, I also dont see why?
0
 
LVL 2

Author Comment

by:softbee
ID: 22820132
Further comment:
The files inside the zip are apparently also looked at on upload, so wrap.cpp is illegal. Can you pick up the file the same as mrwad99. Sorry guys, I usually do my own thing and I am not into the whole internet collaboration deal.
I need this piece of work as part of a POC contract.
Your interest is much appreciated.
0
 
LVL 2

Author Comment

by:softbee
ID: 22820216
Sorry, for a while I did not understand
The link is:
http://www.yousendit.com/download/Y2o5SXQwNXZubVZFQlE9PQ
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 19

Expert Comment

by:LordOfPorts
ID: 22824194
If you go to the Properties of the project and switch from "Use MFC in a Shared DLL" to "Use MFC in a Static Library" does it make a difference?
0
 
LVL 11

Expert Comment

by:alexcohn
ID: 22824274
Your projects compile and run in VisualStudio 2005. The only glitch is that you cannot call CoUninitialize() while a CComPtr<> is in scope. Attached find the fixed version of CTestBenchDlg::OnCloseDevice() function. But this is not for real, you should rather call CoInitialize(NULL) and CoUninitialize() in your WinMain().
void CTestBenchDlg::OnCloseDevice() 

{

    CoInitialize(NULL);

    {

        CComPtr<IUnknown> spUnknown;

        HRESULT hr = spUnknown.CoCreateInstance( __uuidof( DevWrapper ));

        CComPtr<IDevWrapper> pI;

        spUnknown.QueryInterface(&pI);

        long res = 0;

        pI->CloseDevice( &res );

    }

    CoUninitialize();

}

Open in new window

0
 
LVL 2

Author Comment

by:softbee
ID: 22824857
to alexcohn:
I know about that, but I needed this to stay as simple as possible.
Are you telling me that you used my solution 'as is' in VS2005?
If true, then I must attempt to run this in VS2003 EE. Unfortunately i dont have 2005 available.
Please let me know if there was anything else that needed doing.
I will rebuild in the morning and let you know what happened.
I am very relieved that it is possible. There are lots of other dll's that require the same treatment.

to LordOfPorts:
I will have a look at this as well.
0
 
LVL 11

Expert Comment

by:alexcohn
ID: 22825702
Visual Studio converted all three projects for me automatically, and displayed some warnings about obsolete features (like the ordinal numbers for functions exported from the wrapper). But after that, I could simply open the dialog app and press the button.
0
 
LVL 11

Accepted Solution

by:
alexcohn earned 500 total points
ID: 22825869
Oops, I didn't notice that the problematic lines were commented out in CDevWrapper::CloseDevice(), Sorry.

Here is what was wrong. First, the Device/Device.h file needed

class __declspec(dllexport) CDeviceApp : public CWinApp

(you would not experience this if you were using the same file for Device and DevWrap projects; BioDevice.h has it correct).

Second, in CDevWrapper::CloseDevice() you probably intended to write

      iRet = pDev->dllClose();

instead of

      iRet = dllClose();

Third, you need to have Device.dll file next to DevWrap.dll. I simply copied the DLL from Device/Debug to DevWrap/Debug. You can easily set this up forever by coosing the same output directory for both projects.

Fourth, you cannot use operator new for an MFC singleton class CDeviceApp(). I suggest the following fix:

- In Device/Device.cpp, write
     CDeviceApp __declspec(dllexport) theApp;
- In DevWrap/DevWrapper.cpp, write
    extern CDeviceApp __declspec(dllimport) theApp;
- In CDevWrapper::CloseDevice() in DevWrap/DevWrapper.cpp, write
    pDev = &theApp;

That's it. Alternatively, you can use theApp directly:
    iRet = theApp.dllClose();

Probably, you will like to rename the exported theApp object, so that it reflects the DLL name and does not conflict with others (theApp is the name given by default by MFC wizard).

That's it. I hope this will work on VC6 exactly as it does on VS2005. And do not forget to move CoInitialize() and ...uninitialize out of the handler function into the application WinMain().
0
 
LVL 2

Author Comment

by:softbee
ID: 22828835
All is like you predicted. And funnily enough, every comment you made is within my grasp. I was misled by expecting some hocus-pocus to be present in the ATL component.
My sincere thanks.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now