ATL COM dll refuses to implicitly link with MFC dll

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

LVL 2
softbeeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mrwad99Commented:
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
alexcohnCommented:
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
softbeeAuthor Commented:
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
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

softbeeAuthor Commented:
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
softbeeAuthor Commented:
Sorry, for a while I did not understand
The link is:
http://www.yousendit.com/download/Y2o5SXQwNXZubVZFQlE9PQ 
0
LordOfPortsCommented:
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
alexcohnCommented:
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
softbeeAuthor Commented:
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
alexcohnCommented:
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
alexcohnCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
softbeeAuthor Commented:
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.