C++ Unresolved References

I am getting unresolved references and am have a heck of a time trying to sort this out. The reference issues are localized to two class (H/.CPP) files only. These files were part of a .DLL and were moved to a MFC/DLL for troubleshooting.. It seems there is nothing I can change that will make the VS 2010 resolve these references.
The include directories are mapped to the project directory.
The lib directory is mapped to the project directory.


Thanks

1>MyFile.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall _ScheduleFileLock::~_ScheduleFileLock(void)"

#pragma once

// _ScheduleFileLock command target

AFX_STATIC_DATA TCHAR _RCScheduleLock[] = _T("C:\\ENVY\\RCScheduleLock.DAT");
class _ScheduleFileLock : public CObject
{
public:
	_ScheduleFileLock();
	virtual ~_ScheduleFileLock();

	VOID	Dispose();
	BOOL	Disposed();
	BOOL	IsLocked();
	VOID	CreateLock();
	VOID	RemoveLock();
	BOOL	FileExists();



private:
	BOOL	m_bDisposed;
	BOOL	m_bFileLocked;
	BOOL	m_bFileExists;

};

Open in new window


// _ScheduleFileLock.cpp : implementation file
//

#include "stdafx.h"
#include "NvlibMFC.h"
#include "_ScheduleFileLock.h"


// _ScheduleFileLock

_ScheduleFileLock::_ScheduleFileLock()
{
	m_bDisposed = FALSE;
	m_bFileExists = FALSE;
}

_ScheduleFileLock::~_ScheduleFileLock()
{

	Dispose();
}

VOID _ScheduleFileLock::Dispose()
{
	m_bDisposed = TRUE;
}

BOOL _ScheduleFileLock::Disposed()
{
	return m_bDisposed;
}

VOID _ScheduleFileLock::CreateLock()
{
	if (!FileExists())
	{
		CFile cf;
		CFileStatus cfs;
		TRY 
		{
			if (!cf.Open(_RCScheduleLock,CFile::modeCreate | CFile::modeReadWrite))
			{
				CString tmpValue;
				tmpValue= "Schedule Started.";
				cf.Write(tmpValue,tmpValue.GetLength());
				cf.Close();
			}
		}
		CATCH (CFileException, e)
		{

		}
		END_CATCH

	}
}

VOID _ScheduleFileLock::RemoveLock()
{
	if (FileExists())
	{
		CFile cf;
		TRY 
		{
			cf.Remove(_RCScheduleLock);
		}
		CATCH (CFileException, e)
		{

		}
		END_CATCH


	}
}

BOOL _ScheduleFileLock::FileExists()
{
	CFile cf;
	CFileStatus cfs;

	if (!cf.Open(_RCScheduleLock,CFile::modeCreate))
	{
		if (cf.GetStatus(cfs))
		{ // The file exists do nothing
			m_bFileExists = TRUE;
			return TRUE;
		}
	}
	return FALSE;
}

// _ScheduleFileLock member functions

Open in new window

TimPeerAsked:
Who is Participating?
 
Deepu AbrahamConnect With a Mentor R & D Engineering ManagerCommented:
I can see that the destructor is already defined

_ScheduleFileLock::~_ScheduleFileLock()
{

      Dispose();
}

try removing the virtual key word and see. However this is not a solution.
0
 
TimPeerAuthor Commented:
If these files are included in the Main APP, the program compiles fine. No unresolved references.
0
 
TimPeerAuthor Commented:
I tried that. One of may configuration permutations. I managed to get it to work correctly by including the header and implementation in the main project. These documents were getting included / exported from a DLL.

When exporting with DUMPBIN, the dll appeared to not have any named / or ordinal reference ids. A shot in the dark here... but it would seem that maybe an old reference is getting included? I deleted / cleaned and removed all files in the bin and debug directories and checked the property pages for the DLL and the main project. It is sloppy... but if I end up calling the routine from inside the DLL I may just create another named copy of the class.

Another update: After I moved the class to the main program, another class that I was having trouble with, is now working (without any changes to the code or configuration).
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
evilrixConnect With a Mentor Senior Software Engineer (Avast)Commented:
O/T but be careful when starting your symbol names with an underscore as the C++ standard reserves their use:

"Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use."

"Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace"
0
 
sarabandeConnect With a Mentor Commented:
when accessing a dll from an application you normally have a dll and additionally an import library. the import library usually has same name as the dll but extension .lib. it contains wrapper functions to the exported functions of the dll and so the linker would find the called symbols when you add the lib file either to the project tree or to the linker-input settings.

if the dll has no import lib you can't link it directly to your application but would load it dynamically at runtime and call the functions via function pointer. that is not a recommendable way especially when a class should be 'exported'.

note, if you developed the dll with Visual Studio you should get a import lib (or export lib from dll view) with your dll.

Sara
0
 
TimPeerAuthor Commented:
Thanks Sara and evilrix,

Regarding the DLL and export lib. VS is creating the .lib only. I added the _USRDLL preprocessor definition also.

0
 
trinitrotolueneConnect With a Mentor Director - Software EngineeringCommented:
did u try delay loading the dll without using a lib?
0
 
sarabandeConnect With a Mentor Commented:
the expected output of a project can be seen in the project properties in the Linker section

if only a .lib was created but not a .dll i would assume the project is not the one which has created the dll file you tried to access. if you want to solve the dll issue i would suggest to start with a new dll project and move the sources from the current place to the new project folder.

the _USRDLL preprocessor macro is supposed to control  the export/import specifier in the header file of the dll. if the _USRDLL is defined, the specifiers should be __declspec(export) what is needed by the dll project for exporting its functions or classes while the absence of the _USRDLL  should generate the __declspec(import) as needed by projects which would use the dll.

Sara
0
 
TimPeerAuthor Commented:
I have not considered delay loading the dll. I will research what is needed to do this. regarding Sara's comment, I did just as you suggested as a new MFC DLL  project was created and the problematic header and implementation were moved over to it. Compiled, dll created... but continued to load specific functions in the main app resulting in unresolved references.

my project initially had a couple of .H and .CPP files containing many classes. I have since moved the classes to their respective .H and .CPP files. This last class has been a problem since.

Question: is the header information stored in files other than the .lib in VS2010? Maybe a stale reference to the file is persisting in the VS IDE?
0
 
sarabandeConnect With a Mentor Commented:
in you app project did you add the lib generated by the dll project at Linker - Input - Additional Dependencies?

is the path where the lib resides added to the Linker - General - Additional Library Directories ?  (alternatively you could copy the .lib in post build step to one of the known library directories).

note, the header information is (should be) only stored in the .h file of the dll project. the .lib only knows the the names (symbols). so the linker would lookup into the .obj files and .lib files 'linked' to the application project. however in c++ we have a name-mangling where the compiler adds some additionally prefix and suffix to function names to be able to have the same function name twice with different arguments. so the symbol name the linker is looking for has additional information about the argument types and return value type included which is some kind of storing header information with the function name.

the .lib file contains those functions which were specified with the __declspec(export) specifier. you may open the .lib file with a hex editor (for example in visual studio open with ...) and you should see the functions you were calling (+ the name mangling). if not, you need to look for the header file and the _USRDLL preprocessor macro or post the header file here.

Sara


 
0
 
TimPeerAuthor Commented:
the responses didn't address my question. I am, however ,thankful for the response.
0
 
TimPeerAuthor Commented:
The solution provided is relevant for resolving the issue and should stand. In my case, the problem was solved with a different approach. I granted points specifically because the solution is relevant to the question irrespective of the applicability to my issue.

Please ensure these points are issued and the solution is searchable in the Knowledge-base. There are two possible solutions to my question on this kb question.

Tim
0
 
sarabandeCommented:
as you told the responses didn't address your q. i looked once more to your initial question and the error message you posted:

1>MyFile.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall _ScheduleFileLock::~_ScheduleFileLock(void)"


i wonder why in the error is a __declspec(dllimport) while in the class header there is no import/export specifier.

if the class (implementation) was moved to the dll and you want the dll export your class, you need to add a __declspec(dllexport) specifier to the class (statement) in the header.

in your application where you want to use the class you need a __declspec(dllimport) specifier.

to solve both with one header file you could use a preprocessor macro like

#ifdef MYDLL
#define DLL_EXPORT_IMPORT __declspec(dllexport) 
#else
#define DLL_EXPORT_IMPORT __declspec(dllimport)
#endif

DLL_EXPORT_IMPORT class _ScheduleFileLock : public CObject
{
    ...

Open in new window


in the dll project you would add MYDLL to the preprocessor macros and so the export specifier got valid. in the application project you would add no macro and so the import specifier would apply.

what i wonder is the error message which seems to imply that you already used the import specifier. i also wonder that you don't have errors for all other class member functions when you compiled the dll without an export specifier.

the only explanation i have is that the class header you posted is not the original one (what means the right one has the import/export specifiers). if that is true i would assume that you were using an older import library (file) when linking the application against the dll and this library was made before you added the destructor to the class.

Sara
0
 
sarabandeCommented:
as you seem to have the issue only with the virtual destructor, i checked whether it is possible to export a virtual member function of a class derived from a baseclass which comes from an imported (mfc) dll. and that is not allowed. see

http://msdn.microsoft.com/en-us/library/81h27t8c(v=vs.80).aspx

what explains your error and makes the accepted answer of DeepuAbrahamk a valid solution.

Sara
0
 
TimPeerAuthor Commented:
I didn't distribute the points on this question. The moderator did. My choice was to provide the points equally since I received feedback from many on this issue. My issue seems to have been unrelated to the question and subsequent responses and to be fair distributed the points to all with no weighting.

The site moderator seemed to have adjusted the points as he/she deemed appropriate.

Many thanks Sara, your comments were truly appreciated and I will ensure future questions are handled different regarding the issuing of points on questions.

Very best,

Tim
0
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.

All Courses

From novice to tech pro — start learning today.