Solved

Including Global Functions

Posted on 2011-03-21
9
299 Views
Last Modified: 2012-05-11
What is the most efficient way to load a global function one time despite being used in many (.CPP) classes? My application launches a function in a background thread (AfxBeginThread) from many classes in the application.

When I link the application DLL, I get the message:


1>clsGlobals.obj : warning LNK4006: "unsigned int __cdecl MessageThread(void *)" (?MessageThread@@YAIPAX@Z) already defined in helper.obj; second definition ignored

I tried to bury the global function in a .H file. Code snippet below.

#pragma once
#ifndef GLOBALDEFINITIONS_H
#define GLOBALDEFINITIONS_H


#include "Helper.h"
#include "cMsgPacket.h"

 class clsGlobals
{
public:
	clsGlobals(void);
	virtual ~clsGlobals(void);
	
};

UINT MessageThread(LPVOID pParam)
{
	if (pParam)
	{
		CString* lpszMsg = (CString*)pParam;
		AfxMessageBox(*lpszMsg);
		delete lpszMsg;
	}
	return 0;
}
#endif

Open in new window

0
Comment
Question by:TimPeer
  • 5
  • 3
9 Comments
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
I think your snippet has some lines missing - it should end with a
#endif


Are you certain that MessageThread isn't defined somewhere else?
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
Comment Utility
First of all, you should not do that - it is always better to add these in a separate .cpp file. Header guards (http://faculty.cs.niu.edu/~mcmahon/CS241/c241man/node90.html) as you are using them will not prevent you from linker errors, to avoid that one, try the following:
#infdef MessageThread_IMPLEMENTED
UINT MessageThread(LPVOID pParam)
{
	if (pParam)
	{
		CString* lpszMsg = (CString*)pParam;
		AfxMessageBox(*lpszMsg);
		delete lpszMsg;
	}
	return 0;
}
#define MessageThread_IMPLEMENTED
#else
UINT MessageThread(LPVOID pParam); // just a declaration in this case
#endif

Open in new window

0
 

Author Comment

by:TimPeer
Comment Utility
I think I implemented the CPP and H as you described. Here is an example of another... not working.

Here is the message:
1>c:\envy\dev\replicator console\nvlibrary\_nfxthrewdbexception.h(6): error C2144: syntax error : 'void' should be preceded by ';'


Header:
#pragma once
#include "_NDatabase2.h"
#include <afxver_.h>


void AFXAPI NfxThrowDBException(RETCODE nRetCode, _NDatabase* pdb, HSTMT hstmt);

Open in new window


CPP implementation
#include "stdafx.h"
#include "_NFXThrewDBException.h"
#include "_NDatabase2.h"
#include "Helper.h"

#ifndef NfxThrowDBException_IMPLEMENTED

void AFXAPI NfxThrowDBException(RETCODE nRetCode, _NDatabase* pdb, HSTMT hstmt)
{
	_NDBException* pException = new _NDBException();
	if (nRetCode == SQL_ERROR && pdb != NULL)
		pException->BuildErrorString(pdb, hstmt);
	else if (nRetCode > AFX_SQL_ERROR && nRetCode < AFX_SQL_ERROR_MAX)
	{
		VERIFY(pException->m_strError.LoadString(
			AFX_IDP_SQL_FIRST+(nRetCode-AFX_SQL_ERROR)));
		TRACE1("%s\n", pException->m_strError);
	}
	THROW(pException);
}
#define NfxThrowDBException_IMPLEMENTED
#else 

	void AFXAPI NfxThrowDBException(RETCODE nRetCode, _NDatabase* pdb, HSTMT hstmt);

#endif

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Well, in that case I'd check if the file that includes that header file isn't responsible for the missing ';' - the header itself looks healthy.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:TimPeer
Comment Utility
Thank you... It seems your correction worked. The ";" message was caused by the previous header as examined in the compilation log.

A followup please... '#pragma once'. What is the purpose of this precompiler directive?

Thanks again.
0
 

Author Comment

by:TimPeer
Comment Utility
Thank you... It seems your correction worked. The ";" message was caused by the previous header as examined in the compilation log.

A followup please... '#pragma once'. What is the purpose of this precompiler directive?

Thanks again.
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
'#pragma once' has a similar effect as header guards, yet it is specific to VC++ - see http://msdn.microsoft.com/en-us/library/4141z1cx.aspx ("once"): "Specifies that the file will be included (opened) only once by the compiler when compiling a source code file."
0
 

Author Comment

by:TimPeer
Comment Utility
Sorry wrong solution.
0
 

Author Closing Comment

by:TimPeer
Comment Utility
A Correction to your solution. Many thanks for your expert comments on the use of Headers.

#ifndef MessageThread_IMPLEMENTED
UINT MessageThread(LPVOID pParam)
{
      if (pParam)
      {
            CString* lpszMsg = (CString*)pParam;
            AfxMessageBox(*lpszMsg);
            delete lpszMsg;
      }
      return 0;
}
#define MessageThread_IMPLEMENTED
#else
UINT MessageThread(LPVOID pParam); // just a declaration in this case
#endif
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

The following diagram presents a diamond class hierarchy: As depicted, diamond inheritance denotes when two classes (e.g., CDerived1 and CDerived2), separately extending a common base class (e.g., CBase), are sub classed simultaneously by a fourt…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

743 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

17 Experts available now in Live!

Get 1:1 Help Now