Solved

Including Global Functions

Posted on 2011-03-21
9
305 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
ID: 35183472
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
ID: 35183722
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
ID: 35184666
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
Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

 
LVL 86

Expert Comment

by:jkr
ID: 35184703
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
 

Author Comment

by:TimPeer
ID: 35185406
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
ID: 35185407
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
ID: 35185455
'#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
ID: 35185475
Sorry wrong solution.
0
 

Author Closing Comment

by:TimPeer
ID: 35185476
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

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
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 learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

770 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