Re: How to create a tool header file without symbol duplication error
in VC?
Learning_Everyday wrote:
I am trying to write a tool header file to be used for many projects.
However, I am always getting the symbol duplication error.
I have tried to use the following trick to allow my code to be included
once:
#ifndef _HOOKENGINE_H
#define _HOOKENGINE_H
....
[code]
#endif
However, I am still getting the multiple definition errors:
Error 1 error LNK2005: "void __cdecl MyPrintf(wchar_t const *,...)"
(?MyPrintf@@YAXPB_WZZ) already defined in HookEngine.obj dllmain.obj
Error 2 error LNK2005: "void __cdecl Test(void)" (?Test@@YAXXZ) already
defined in HookEngine.obj dllmain.obj
Error 3 fatal error LNK1169: one or more multiply defined symbols found
D:\Program\Win32\HookEngine\Debug\HookEngine.dll 1
Can anyone tell me the reason? Thanks!
extern void __cdecl MyPrintf(LPCTSTR lpszFormat, ...);
#ifndef _HOOKENGINE_H
#define _HOOKENGINE_H
#define MAX_PRINT_STRING 1024
//#define MSG_BOX_PRINT
#ifdef _DEBUG
#define MSG_DEBUG_PRINT
#endif
#define MSG_DEBUG_PRINT
#ifdef MSG_FILE_PRINT
TCHAR szFilePrint[MAX_PATH] = TEXT("c:\\out.txt");
BOOL bZeroFile = FALSE;
#endif
void __cdecl MyPrintf(LPCTSTR lpszFormat, ...)
{
TCHAR szOutput[MAX_PRINT_STRING]; // max printable string length
va_list v1;
va_start(v1, lpszFormat);
//DebugBreak();
StringCchVPrintf(szOutput, MAX_PRINT_STRING, lpszFormat, v1);
#ifdef MSG_DEBUG_PRINT
OutputDebugString(szOutput);
#endif
#ifdef MSG_CONSOLE_PRINT
_tprintf(TEXT("%s"), szOutput);
#endif
#ifdef MSG_BOX_PRINT
MessageBox(NULL, szOutput, TEXT("MyPrintf Output"), MB_OK);
#endif
#ifdef MSG_FILE_PRINT
{
static HANDLE hFile = NULL;
DWORD dwNumWritten;
if (hFile == NULL)
{
hFile = CreateFile(szFilePrint, GENERIC_WRITE, FILE_SHARE_READ |
FILE_SHARE_WRITE, NULL,
bZeroFile ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
//if (hFile == INVALID_HANDLE_VALUE)
// MyPrintf("CreateFile output log file %s failed with %s\r\n",
szFilePrint, FormatError(GetLastError()));
}
if (hFile != INVALID_HANDLE_VALUE)
{
OVERLAPPED ol = {0};
LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &ol);
SetFilePointer(hFile, 0, 0, FILE_END);
WriteFile(hFile, szOutput, lstrlen(szOutput)*sizeof(TCHAR),
&dwNumWritten, NULL);
UnlockFileEx(hFile, 0, 1, 0, &ol);
}
}
#endif
}
#endif
LE:
Include guards prevent multiple inclusion of the header in a given translation
unit (which can cause compile errors). You are seeing multiple definition in
different translation units (which is a linker error).
This is happening to you because you are putting both the declaration and the
definition of MyPrintf in the header. You should either move the definition to a
..cpp file, or use the inline keyword on the definition. In the latter case, you
can get rid of the declaration.
[I am assuming that you are using C++, not C.]
--
David Wilkinson
Visual C++ MVP