Need help with VC++ 2005 linking error. unresolved external symbol "wchar_t * __cdecl uxdup(char const *)"

Hi.  I was given a new task to update a project created in VC++ 2003 to VC++ 2005.
I fixed multiple compile errors, but now I receive linking errors which seem a lot harder to figure out.  I got a linking error regarding "LIBCP.LIB", but someone else told me to specify that in "Ignore specific library" in options and that message would go away.  I was also told that "LIBCMT.LIB" replaces "LIBCP.LIB", but wasn't told if anything needed to be done for that.  Anyways, I now receive the following warning and error messages:  (this probably is not enough info to solve the problem, but I need to know how to approach this problem - remember I did not write the code, but need to get it to compile in VC++ 2005.  Thanks)

Generating Code...
Compiling resources...
Linking...
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllCanUnloadNow' should not be assigned an ordinal
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllGetClassObject' should not be assigned an ordinal
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllRegisterServer' should not be assigned an ordinal
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllUnregisterServer' should not be assigned an ordinal
   Creating library .\..\..\bin\Release/Suite_CCSPic.lib and object .\..\..\bin\Release/Suite_CCSPic.exp

T_CCSPICcc.obj : error LNK2001: unresolved external symbol "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z)

LoggedException.obj : error LNK2019: unresolved external symbol "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z) referenced in function "public: __thiscall String816::operator char const *(void)" (??BString816@@QAEPBDXZ)

LSC.obj : error LNK2001: unresolved external symbol "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z)

S_CCSPIC.obj : error LNK2001: unresolved external symbol "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z)

Suite_CCSPic.obj : error LNK2001: unresolved external symbol "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z)

LSC.obj : error LNK2019: unresolved external symbol "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z) referenced in function "public: __thiscall String816::operator wchar_t const *(void)" (??BString816@@QAEPB_WXZ)

S_CCSPIC.obj : error LNK2001: unresolved external symbol "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z)

T_CCSPICcc.obj : error LNK2001: unresolved external symbol "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z)

.\..\..\bin\Release/Suite_CCSPic.dll : fatal error LNK1120: 2 unresolved externals



 
 
jmatyasAsked:
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.

jkrCommented:
>>I was also told that "LIBCMT.LIB" replaces "LIBCP.LIB", but wasn't told if anything needed to be done for that

Not really. You still should link with LIBCP.LIB. Maybe that's where the problem comes from. Apart from that, 'String816' seems to be part of Don Box' 'YACL' - are you forgetting to link with that lib?
jkrCommented:
BTW, from what I can find on the web, 'uxdup()' returns the UNICODE equivalent of an ANSI string (the way 'strdup()' would,, so you could just 'roll your own' and supply that, e.g.

wchar_t* uxdup(char* psz) {

size_t len = strlen(psz) + 1;
wchar_t* pwsz = new wchar_t[len];

mbstowcs(pwsz,psz,len);

return pwsz;
}
itsmeandnobodyelseCommented:
>>>> LNK4222

That warning comes if your dll exports the shown functions via a  .def  file by ordinal numbers.  The Dll--- functions should be exported by name via a declspec(dllexport) directive. Edit the .def file and remove the functions shown in the warnings.

>>>> uxdup(char const *)

Seems to be a UNIX function. Do you know where it is used and why? If it is a private function you may switch off C++ name mangling by using an extern C clause before declarating uxdup:

#ifdef __cplusplus
extern "C"
{
#endif

wchar_t * uxdup(char const *);

#ifdef __cplusplus
}
#endif

if uxdup is declared in a header you might move the include of that header within an extern scope.

Regards, Alex





Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

itsmeandnobodyelseCommented:
>>>> from what I can find on the web

Good, jkr. I didn't find any valuable.
jkrCommented:
Actually, there is only one useful reference:

http://groups.google.com/groups?q=uxdup

which uses it as

#ifdef UNICODE
        hr = fpInst( (fUnreg ? FALSE : TRUE), cmdline);
#else
        hr = fpInst( (fUnreg ? FALSE : TRUE), uxdup (cmdline));
#endif

Given that the errors are from 'String816', which turns out to be a class in 'Yet Another COM Library' by Don Box, the 'strdup()'-like conversion seems to be its only purpose. Replacing it with ATL's 'A2W()' would be another option.
jkrCommented:
Ooops, BTW, the signature should be

#ifdef __cplusplus
extern "C"
#endif
wchar_t* __cdecl uxdup(const char* psz) {

size_t len = strlen(psz) + 1;
wchar_t* pwsz = new wchar_t[len];

mbstowcs(pwsz,psz,len);

return pwsz;
}
jmatyasAuthor Commented:
Thanks for your feedback.  I am somewhat of a newbie to COM and ATL, but  familiar with C++ (at least most of it).  Although no linking errors came from "ustring.h", I think it might be my problem file.  The file name is ustring.h , but it says ustring.cpp on the first comment line in the code.  It also is the only file in my project that has both text strings "uxdup" and "String816" which are both listed in the linker error output.

I don't know how to attach the file as an attachment, so I will paste the whole file as text below.  Thanks again for your previous advice.  Any further responses are greatly appreciated.

USTRING.H
================================
///////////////////////////////////////////////////////////////////////////////
//
// ustring.cpp - Copyright 1997, Don Box
//
// This file contains overloaded ustrcpy, ustrcat, and ustrlen that
// take either wchar_t or char strings for either argument and map to
// the appropriate CRT routine to do the work. The routines are inlined
// and incur no additional overhead.
//
//     size_t ustrlen(const uchar *p);
//     uchar *ustrcpy(uchar *p1, const uchar *p2);
//     uchar *ustrcat(uchar *p1, const uchar *p2);
//
// where uchar = { wchar_t , char }
//
// This file contains the prototypes for several conversion routines
// that are used by the String816 class for duplicating/converting strings
// on the fly.
//
//     uxdup(const char *psz) - returns a new-ed wchar_t string based on psz
//     uxdup(const wchar_t *psz) - returns a new-ed char string based on psz
//    
// Finally, this file contains two class definitions:
//
//     _U - converts const uchar * to const uchar *
//     _UNCC - converts const uchar * to uchar * (needed for non-const correct code)
//
// Usage:
/*

void f(const OLECHAR *pwsz, HWND hwnd)
{
    TCHAR sz[MAX_PATH];
    GUID guid;
    ustrcpy(sz, pwsz); // overloads to correct copy/conversion routine
    SetWindowText(hwnd, _U(pwsz)); // _U temporarily dups buffer if needed
    GetWindowText(hwnd, sz, MAX_PATH);
    CLSIDFromString(_UNCC(sz), &guid); // _UNCC needed because api non-const-correct
}

*/

#ifndef _USTR_H
#define _USTR_H

#include <limits.h>
#include <stdio.h>
#include <stdarg.h>

///////////////////////////////////////////////////////////////////////////////
// Begin Extensions

#include "bsd_string.h"

// All of these functions aren't part of Don Box's original ustring library.

inline int uisalpha(int c)
{
    return isalpha(c);
}

inline int uisalpha(wint_t c)
{
    return iswalpha(c);
}

inline int utoupper(int c)
{
    return toupper(c);
}

inline int utoupper(wint_t c)
{
    return towupper(c);
}

inline int usprintf(char* pszBuffer, const char* pszFormat, ...)
{
    va_list Args;
    va_start(Args, pszFormat);
    int n = vsprintf(pszBuffer, pszFormat, Args);
    va_end(Args);
    return n;
}

inline int usprintf(wchar_t* pwszBuffer, const wchar_t* pwszFormat, ...)
{
    va_list Args;
    va_start(Args, pwszFormat);
    int n = vswprintf(pwszBuffer, pwszFormat, Args);
    va_end(Args);
    return n;
}

inline char* ustrstr(const char* psz1, const char* psz2)
{
    return (char *) strstr(psz1, psz2);
}

inline wchar_t* ustrstr(const wchar_t* psz1, const wchar_t* psz2)
{
    return (wchar_t *) wcsstr(psz1, psz2);
}

inline char* ustrchr(const char* psz, const int c)
{
    return (char *) strchr(psz, c);
}

inline wchar_t* ustrchr(const wchar_t* psz, const int c)
{
    return (wchar_t *) wcschr(psz, c);
}

inline char* ustrrchr(const char* psz, const int c)
{
    return (char *) strrchr(psz, c);
}

inline wchar_t* ustrrchr(const wchar_t* psz, const int c)
{
    return (wchar_t *) wcsrchr(psz, c);
}

inline int ustrcmp(const char* psz1, const char* psz2)
{
    return strcmp(psz1, psz2);
}

inline int ustrcmp(const wchar_t* psz1, const wchar_t* psz2)
{
    return wcscmp(psz1, psz2);
}

inline int ustrncmp(const char* psz1, const char* psz2, size_t nLength)
{
    return strncmp(psz1, psz2, nLength);
}

inline int ustrncmp(const wchar_t* psz1, const wchar_t* psz2, size_t nLength)
{
    return wcsncmp(psz1, psz2, nLength);
}

inline int ustricmp(const char* psz1, const char* psz2)
{
    return stricmp(psz1, psz2);
}

inline int ustricmp(const wchar_t* psz1, const wchar_t* psz2)
{
    return wcsicmp(psz1, psz2);
}

inline char *ustrncpy(char *pszTarget, const wchar_t *pszSrc,
                      const size_t nLength)
{
    return wcstombs(pszTarget, pszSrc, nLength), pszTarget;
}

inline wchar_t *ustrncpy(wchar_t *pszTarget, const wchar_t *pszSrc,
                         const size_t nLength)
{
    return wcsncpy(pszTarget, pszSrc, nLength), pszTarget;
}

inline size_t ustrlcpy(char* pszDst, const char* pszSrc, size_t uSize)
{
    return strlcpy(pszDst, pszSrc, uSize);;
}

inline size_t ustrlcpy(char* pszDst, const wchar_t* pwszSrc, size_t uSize)
{
    return char_wchar_lcpy(pszDst, pwszSrc, uSize);
}

inline size_t ustrlcpy(wchar_t* pwszDst, const char* pszSrc, size_t uSize)
{
    return wchar_char_lcpy(pwszDst, pszSrc, uSize);
}

inline size_t ustrlcpy(wchar_t* pwszDst, const wchar_t* pwszSrc, size_t uSize)
{
    return wcslcpy(pwszDst, pwszSrc, uSize);
}

inline size_t ustrlcat(char* pszDst, const char* pszSrc, size_t uSize)
{
    return strlcat(pszDst, pszSrc, uSize);
}

inline size_t ustrlcat(char* pszDst, const wchar_t* pwszSrc, size_t uSize)
{
    return char_wchar_lcat(pszDst, pwszSrc, uSize);
}

inline size_t ustrlcat(wchar_t* pwszDst, const char* pszSrc, size_t uSize)
{
    return wchar_char_lcat(pwszDst, pszSrc, uSize);
}

inline size_t ustrlcat(wchar_t* pwszDst, const wchar_t* pwszSrc, size_t uSize)
{
    return wcslcat(pwszDst, pwszSrc, uSize);
}

// End Extensions
///////////////////////////////////////////////////////////////////////////////

inline size_t ustrlen(const wchar_t *psz)
{
    return wcslen(psz);
}

inline size_t ustrlen(const char *psz)
{
    return strlen(psz);
}

inline char *ustrcpy(char *pszTarget, const wchar_t *pszSrc)
{
    return wcstombs(pszTarget, pszSrc, INT_MAX), pszTarget;
}

inline wchar_t *ustrcpy(wchar_t *pszTarget, const wchar_t *pszSrc)
{
    return wcscpy(pszTarget, pszSrc), pszTarget;
}

inline char *ustrcpy(char *pszTarget, const char *pszSrc)
{
    return strcpy(pszTarget, pszSrc), pszTarget;
}

inline wchar_t *ustrcpy(wchar_t *pszTarget, const char *pszSrc)
{
    return mbstowcs(pszTarget, pszSrc, INT_MAX), pszTarget;
}

inline char *ustrncpy(char *pszTarget, const char *pszSrc, size_t nLength)
{
    return strncpy(pszTarget, pszSrc, nLength), pszTarget;
}

inline wchar_t *ustrncpy(wchar_t *pszTarget, const char *pszSrc,
                         size_t nLength)
{
    return mbstowcs(pszTarget, pszSrc, nLength), pszTarget;
}

inline char *ustrcat(char *pszTarget, const wchar_t *pszSrc)
{
    return wcstombs(pszTarget + ustrlen(pszTarget), pszSrc, INT_MAX), pszTarget;
}

inline wchar_t *ustrcat(wchar_t *pszTarget, const wchar_t *pszSrc)
{
    return wcscat(pszTarget, pszSrc);
}

inline char *ustrcat(char *pszTarget, const char *pszSrc)
{
    return strcat(pszTarget, pszSrc);
}

inline wchar_t *ustrcat(wchar_t *pszTarget, const char *pszSrc)
{
    return mbstowcs(pszTarget + ustrlen(pszTarget), pszSrc, INT_MAX), pszTarget;
}

// these two routines are equivalent to strdup but convert
// instead of just copying

wchar_t *uxdup(const char *psz);
char *uxdup(const wchar_t *pwsz);


// String816 maps const wchar_t * and const char * to
// either const wchar_t * or const char * depending on context
class String816
{
    wchar_t *m_pwsz;
    char    *m_psz;
    BOOL     m_bIsWide;
public:
    String816(const char *psz)
        : m_pwsz(0), m_psz((char*)psz), m_bIsWide(FALSE)
    {
    }

    String816(const wchar_t *pwsz)
        : m_pwsz((wchar_t*)pwsz), m_psz(0), m_bIsWide(TRUE)
    {
    }

    operator const wchar_t * (void)
    {
        if (!m_bIsWide && m_pwsz == 0)
            m_pwsz = uxdup(m_psz);
        return m_pwsz;
    }

    operator const char * (void)
    {
        if (m_bIsWide && m_psz == 0)
            m_psz = uxdup(m_pwsz);
        return m_psz;
    }

    ~String816(void)
    {
        if (m_bIsWide && m_psz)
            free(m_psz);
        else if (!m_bIsWide && m_pwsz)
            free(m_pwsz);
    }
};

// Often it is algorithmically convenient to be able to pass zero to the
// String816 class, and just get zero back from the conversion operators.
// Here's an extension of String816 that does just that.
class String816_SafeOnZero
{
    wchar_t *m_pwsz;
    char    *m_psz;
    BOOL     m_bIsWide;
public:
    String816_SafeOnZero(const char *psz)
        : m_pwsz(0), m_psz((char*)psz), m_bIsWide(FALSE)
    {
    }

    String816_SafeOnZero(const wchar_t *pwsz)
        : m_pwsz((wchar_t*)pwsz), m_psz(0), m_bIsWide(TRUE)
    {
    }

    operator const wchar_t * (void)
    {
        if (!m_pwsz && !m_psz)
            return 0;
        if (!m_bIsWide && m_pwsz == 0)
            m_pwsz = uxdup(m_psz);
        return m_pwsz;
    }

    operator const char * (void)
    {
        if (!m_pwsz && !m_psz)
            return 0;
        if (m_bIsWide && m_psz == 0)
            m_psz = uxdup(m_pwsz);
        return m_psz;
    }

    ~String816_SafeOnZero(void)
    {
        if (m_bIsWide && m_psz)
            free(m_psz);
        else if (!m_bIsWide && m_pwsz)
            free(m_pwsz);
    }
};

class Character816
{
    wchar_t m_wc;
    char m_c;
    BOOL m_bIsWide;
public:
    Character816(const char c)
        : m_wc(0), m_c(c), m_bIsWide(FALSE)
    {
    }

    Character816(const wchar_t wc)
        : m_wc(wc), m_c(0), m_bIsWide(TRUE)
    {
    }

    operator const wchar_t (void)
    {
        #pragma warning(disable : 4172)
        if (m_bIsWide)
            return m_wc;
        return (wchar_t) m_c;
        #pragma warning(default : 4172)
    }

    operator const char (void)
    {
        #pragma warning(disable : 4172)
        if (m_bIsWide)
            return (char) m_wc;
        return m_c;
        #pragma warning(default : 4172)
    }

    // We have this operator so we can do equality comparisons against other
    // characters.
    operator const int (void)
    {
        #pragma warning(disable : 4172)
        if (m_bIsWide)
            return (int) m_wc;
        return (int) m_c;
        #pragma warning(default : 4172)
    }
};

typedef String816 _U;
typedef String816_SafeOnZero __U;
typedef Character816 _u;
// class _UNCC adds non-const conversion operators to String816
class _UNCC : public String816
{
public:
    _UNCC(const char *psz)
        : String816(psz)
    {
    }

    _UNCC(const wchar_t *pwsz)
        : String816(pwsz)
    {
    }

    operator wchar_t * (void)
    {
        return (wchar_t*)operator const wchar_t *();
    }

    operator char * (void)
    {
        return (char*)operator const char *();
    }

};

#endif
 

jkrCommented:
There we have the reason, the declaration is there, but the implementation is missing - just add

#include <stdlib.h>
#ifdef __cplusplus
extern "C"
#endif
wchar_t* __cdecl uxdup(const char* psz) {

size_t len = strlen(psz) + 1;
wchar_t* pwsz = new wchar_t[len];

mbstowcs(pwsz,psz,len);

return pwsz;
}

to the file you posted, preferrably at the end.

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
jmatyasAuthor Commented:
I also had a separate question on the above code.  What exactly does the following code do in the String816 class?  The only time I used "operator" was to overload operators (such as +,-,*,++) for the class I was defining.  

    operator const wchar_t (void)
    {
        #pragma warning(disable : 4172)
        if (m_bIsWide)
            return m_wc;
        return (wchar_t) m_c;
        #pragma warning(default : 4172)
    }

    operator const char (void)
    {
        #pragma warning(disable : 4172)
        if (m_bIsWide)
            return (char) m_wc;
        return m_c;
        #pragma warning(default : 4172)
    }


itsmeandnobodyelseCommented:
>>>> wchar_t *uxdup(const char *psz);
>>>> char *uxdup(const wchar_t *pwsz);

Seems, there are two uxdup functions missing


#ifdef __cplusplus
extern "C"
#endif

wchar_t* uxdup(const char* psz)
{
   int           len = strlen(psz);
   wchar_t* pwsz = new wchar_t[len+1];
   mbstowcs(pwsz, psz, len);
   return pwsz;
}

char *uxdup(const wchar_t *pwsz)
{
   int       len = wstrlen(pwsz);
   char*  psz = new char[len*2+1];
   if (wcstombs(psz, pwsz, len) == (size_t)-1)
        *psz=0;
   
   return psz;  
}

#ifdef __cplusplus
}     // close the brackets
#endif


Regards, Alex
jkrCommented:
>>What exactly does the following code do in the String816 class?

It takes care of implicit and explicit conversions by providing the appropriate operators, so you can just write

String816 str;

//...

cout << (char) str << endl; // explicit



itsmeandnobodyelseCommented:
>>>>  I also had a separate question on the above code.

These operator functions are so-called "cast operators". If you assign a String816 to a char* or a wchar_t* the "casting" is done by these operators. Also, if an interface requires a const char* or a const wchar_t* and you pass a String816 istead the conversion is made automatically (thus avoiding to use member functions like c_str() ).

Regards
jkrCommented:
Argh, that shold have been

cout << (char*) str << endl; // explicit

Or with respect that you posted the operators for Character816

Character816 c;

//...

cout << (char) c<< endl; // explicit
jmatyasAuthor Commented:
Thanks for all the feedback.  This really helps me out.  I think I know what to do after two final questions.

1)  What purpose does "__cdecl" serve in the function definition?
     I read something on the internet, but it was not very clear.

2)  Which line of code is correct for function uxdup(const char* psz)?

     size_t len = strlen(psz) + 1;
     OR
     int len = strlen(psz);
jmatyasAuthor Commented:
Thanks for the code segment.  When I added the above code (re-pasted below) into the bottom of ustring.h, except stdlib.h near top, I get numerous error messages (line numbers included to help):

Is there a "{" missing to match the "}" in line 467?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <limits.h>  // (line 46) always here
#include <stdio.h>  // (line 47) always here
#include <stdarg.h>  // (line 48) always here
#include <stdlib.h>  // (line 49) added today
...
...
#ifdef __cplusplus   // (line 443)
extern "C"
#endif       // (line 445)

//  Code added to define uxdup
wchar_t* uxdup(const char* psz)
{
   int len = strlen(psz); // or size_t len = strlen(psz) + 1;  // (line 450)
   wchar_t* pwsz = new wchar_t[len+1];
   mbstowcs(pwsz, psz, len);
   return pwsz;
}
   // (line 455)
char *uxdup(const wchar_t *pwsz)
{
   int       len = wstrlen(pwsz);
   char*  psz = new char[len*2+1];
   if (wcstombs(psz, pwsz, len) == (size_t)-1)  // (line 460)
        *psz=0;
   
   return psz;  
}

#ifdef __cplusplus
}     // close the brackets   (line 467)
#endif
+++++++++++++++++++++++++++++++++++++++++++++++++++++
..\include\ustring.h(449) : error C2732: linkage specification contradicts earlier specification for 'uxdup'
        ..\include\ustring.h(448) : see declaration of 'uxdup'
..\include\ustring.h(458) : error C3861: 'wstrlen': identifier not found
..\include\ustring.h(467) : error C2059: syntax error : '}'
..\include\ustring.h(467) : error C2143: syntax error : missing ';' before '}'
..\include\ustring.h(467) : error C2059: syntax error : '}'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(449) : error C2143: syntax error : missing ';' before '{'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(449) : error C2447: '{' : missing function header (old-style formal list?)
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(457) : error C2084: function 'char *uxdup(const wchar_t *)' already has a body
        c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(275) : see previous definition of 'uxdup'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(458) : error C3861: 'wstrlen': identifier not found
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(467) : error C2059: syntax error : '}'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(467) : error C2143: syntax error : missing ';' before '}'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(467) : error C2059: syntax error : '}'
..\include\pathx.h(142) : error C2143: syntax error : missing ';' before '{'
..\include\pathx.h(142) : error C2447: '{' : missing function header (old-style formal list?)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
If I comment out these two lines:
wchar_t *uxdup(const char *psz);
char *uxdup(const wchar_t *pwsz);

The compile errors change slightly:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
..\include\ustring.h(299) : error C3861: 'uxdup': identifier not found
..\include\ustring.h(306) : error C3861: 'uxdup': identifier not found
..\include\ustring.h(343) : error C3861: 'uxdup': identifier not found
..\include\ustring.h(352) : error C3861: 'uxdup': identifier not found
..\include\ustring.h(449) : error C2365: 'uxdup' : redefinition; previous definition was 'formerly unknown identifier'
..\include\ustring.h(457) : error C2365: 'uxdup' : redefinition; previous definition was 'formerly unknown identifier'
..\include\ustring.h(458) : error C3861: 'wstrlen': identifier not found
..\include\ustring.h(467) : error C2059: syntax error : '}'
..\include\ustring.h(467) : error C2143: syntax error : missing ';' before '}'
..\include\ustring.h(467) : error C2059: syntax error : '}'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(449) : error C2143: syntax error : missing ';' before '{'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(449) : error C2447: '{' : missing function header (old-style formal list?)
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(457) : error C2365: 'uxdup' : redefinition; previous definition was 'formerly unknown identifier'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(458) : error C3861: 'wstrlen': identifier not found
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(467) : error C2059: syntax error : '}'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(467) : error C2143: syntax error : missing ';' before '}'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(467) : error C2059: syntax error : '}'
..\include\pathx.h(142) : error C2143: syntax error : missing ';' before '{'
..\include\pathx.h(142) : error C2447: '{' : missing function header (old-style formal list?)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Hopefully this is something simple to fix to get this thing to compile.  
jkrCommented:
That should be

#ifdef __cplusplus   // (line 443)
extern "C" { // <------------- '{' was missing.
#endif       // (line 445)
jkrCommented:
>>1)  What purpose does "__cdecl" serve in the function definition?

It specifies the calling convention. There are differences how parameters are pushed and popped from the stack when calling a function, and this one specifies the 'C calling convention', which is the default calling convention for C and C++ programs. Because the stack is cleaned up by the caller, it can do vararg functions

>>2)  Which line of code is correct for function uxdup(const char* psz)?

     size_t len = strlen(psz) + 1;

That's the correct one in any case, since in addition to the actual number of characters, you'll have to add the terminating NULL byte.
itsmeandnobodyelseCommented:
>>>>     size_t len = strlen(psz) + 1;
>>>>     OR
>>>>     int len = strlen(psz);

They are both correct. The first tries to calculate the size of the destination size. The second determines the string length in bytes which is one less than the needed size. You could see that in both cases the same amount of bytes was allocated:

A:      wchar_t* pwsz = new wchar_t[len];
 
B:      wchar_t* pwsz = new wchar_t[len+1];

I prefer the second way cause a variable called 'len' shouldn't have an extra byte for the terminating zero cause a length doesn't include that.

Note, it doesn't matter whether to use an 'int' or 'size_t' what is an 'unsigned int'. There are no negative numbers involved in the statements where the variable was used.

Regards, Alex
jmatyasAuthor Commented:
Thanks for clarifying and answering my two questions.  You guys really know your stuff, and I can't wait to award you points when this problem gets finished.

I think the problem is almost complete.  I put the "{" to match the brackets, and now I receive 8 compile errors.  I looked at my C++ book to see what could be wrong, but can't determine the exact problem just by looking.  Why is the compiler complaining?

Here's the code along with line numbers and the compile error messages (2 sets of compile errors, with and without lines 275 and 276):

#include <limits.h>    // line 46
#include <stdio.h>    // line 47
#include <stdarg.h>  // line 48
#include <stdlib.h>   // line 49
....
wchar_t *uxdup(const char *psz);     // line 275
char *uxdup(const wchar_t *pwsz);  // line 276
....
....
//  Code added to define uxdup
wchar_t* uxdup(const char* psz)  // line 448
{                                                
   size_t len = strlen(psz) + 1;      // line 450
   wchar_t* pwsz = new wchar_t[len+1];
   mbstowcs(pwsz, psz, len);      
   return pwsz;
}
                                             
char *uxdup(const wchar_t *pwsz)  // line 456
{
   int       len = wstrlen(pwsz);           // line 458
   char*  psz = new char[len*2+1];
   if (wcstombs(psz, pwsz, len) == (size_t)-1)
        *psz=0;
   
   return psz;  
}


..\include\ustring.h(449) : error C2732: linkage specification contradicts earlier specification for 'uxdup'
        ..\include\ustring.h(448) : see declaration of 'uxdup'
..\include\ustring.h(457) : error C2732: linkage specification contradicts earlier specification for 'uxdup'
        ..\include\ustring.h(456) : see declaration of 'uxdup'
..\include\ustring.h(458) : error C3861: 'wstrlen': identifier not found
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(449) : error C2084: function 'wchar_t *uxdup(const char *)' already has a body
        c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(275) : see previous definition of 'uxdup'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(449) : error C2732: linkage specification contradicts earlier specification for 'uxdup'
        c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(448) : see declaration of 'uxdup'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(457) : error C2084: function 'char *uxdup(const wchar_t *)' already has a body
        c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(276) : see previous definition of 'uxdup'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(457) : error C2732: linkage specification contradicts earlier specification for 'uxdup'
        c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(456) : see declaration of 'uxdup'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(458) : error C3861: 'wstrlen': identifier not found
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
If I comment out lines 275 and 276.  I get greatly different compile error messages:

..\include\ustring.h(300) : error C3861: 'uxdup': identifier not found
..\include\ustring.h(307) : error C3861: 'uxdup': identifier not found
..\include\ustring.h(344) : error C3861: 'uxdup': identifier not found
..\include\ustring.h(353) : error C3861: 'uxdup': identifier not found
..\include\ustring.h(449) : error C2365: 'uxdup' : redefinition; previous definition was 'formerly unknown identifier'
..\include\ustring.h(457) : error C2365: 'uxdup' : redefinition; previous definition was 'formerly unknown identifier'
..\include\ustring.h(458) : error C3861: 'wstrlen': identifier not found
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(449) : error C2365: 'uxdup' : redefinition; previous definition was 'formerly unknown identifier'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(457) : error C2365: 'uxdup' : redefinition; previous definition was 'formerly unknown identifier'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(458) : error C3861: 'wstrlen': identifier not found  



jkrCommented:
Have you tried to remove the 'extern "C"'?
jmatyasAuthor Commented:
If I remove (comment out) the 'extern "C"' code, I get compile errors, but fewer of them.  Only 4 errors instead of 8.

..\include\ustring.h(459) : error C3861: 'wstrlen': identifier not found
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(450) : error C2084: function 'wchar_t *uxdup(const char *)' already has a body
        c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(275) : see previous definition of 'uxdup'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(458) : error C2084: function 'char *uxdup(const wchar_t *)' already has a body
        c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(276) : see previous definition of 'uxdup'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(459) : error C3861: 'wstrlen': identifier not found
jmatyasAuthor Commented:
I moved the two functions from the bottom to the middle where the "stubs" (now removed) used to be.  Now I get only one compile error message.

..\include\ustring.h(289) : error C3861: 'wstrlen': identifier not found

I tried adding "#include <wstring.h>", but that didn't help.
wchar_t is recognized, so I don't know why wstrlen can't be found.

jkrCommented:
>>..\include\ustring.h(459) : error C3861: 'wstrlen': identifier not found

There is no 'wstrlen()', that has to be 'wcslen()'

The rest should go away with the proper declarations, e.g.

wchar_t* uxdup(const char* psz);
char *uxdup(const wchar_t *pwsz);

wchar_t* uxdup(const char* psz)
{
   int len = strlen(psz); // or size_t len = strlen(psz) + 1;  // (line 450)
   wchar_t* pwsz = new wchar_t[len]; // no need for '+1'
   mbstowcs(pwsz, psz, len);
   return pwsz;
}

char *uxdup(const wchar_t *pwsz)
{
   int       len = wcslen(pwsz) + 1;
   char*  psz = new char[len]; // just use 'len' as calculated above, the buffer is large enough
   if (wcstombs(psz, pwsz, len) == (size_t)-1)  // (line 460)
        *psz=0;
   
   return psz;  
}
itsmeandnobodyelseCommented:
>>>> wstrlen

change it to wcslen

>>>> C2732: linkage specification contradicts earlier specification for 'uxdup'

That came from the extern "C". Remove the extern "C" scope in your source as jkr suggested. In ustring.h uxdup was used but not with C linkage. C linkage is necessary if using C functions from a C runtime DLL (what doesn't apply to uxdup). Here, we have a C++ function cause it was used without extern "C" in some other module.

Regards, Alex
itsmeandnobodyelseCommented:
Seems I needed too much time to answer ...
jmatyasAuthor Commented:
My system can not find wstring.h , so I did some research on the net.
I replaced "wstrlen" (wstring.h) with "wcslen" (string.h or wchar.h) and now my project compiles, but now I get linking errors again.  This time the linking errors are different, saying the subroutines are already defined.  I believe this is due to removing the #IFDEF code, but when I have that code in there, I get compiler errors, so I am sorta running in circles.

LSC.obj : error LNK2005: "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z) already defined in LoggedException.obj
LSC.obj : error LNK2005: "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z) already defined in LoggedException.obj
ParseMsgLine.obj : error LNK2005: "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z) already defined in LoggedException.obj
ParseMsgLine.obj : error LNK2005: "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z) already defined in LoggedException.obj
RegPathString.obj : error LNK2005: "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z) already defined in LoggedException.obj
RegPathString.obj : error LNK2005: "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z) already defined in LoggedException.obj
S_CCSPIC.obj : error LNK2005: "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z) already defined in LoggedException.obj
S_CCSPIC.obj : error LNK2005: "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z) already defined in LoggedException.obj
StdAfx.obj : error LNK2005: "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z) already defined in LoggedException.obj
StdAfx.obj : error LNK2005: "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z) already defined in LoggedException.obj
Suite_CCSPic.obj : error LNK2005: "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z) already defined in LoggedException.obj
T_CCSPICcc.obj : error LNK2005: "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z) already defined in LoggedException.obj
T_CCSPICcc.obj : error LNK2005: "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z) already defined in LoggedException.obj
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllCanUnloadNow' should not be assigned an ordinal
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllGetClassObject' should not be assigned an ordinal
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllRegisterServer' should not be assigned an ordinal
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllUnregisterServer' should not be assigned an ordinal
jmatyasAuthor Commented:
When I have the code broken up like this, I get two compiler error messages:
+++++++++++++++++++++++++++++++++++++++++++++++++
wchar_t* uxdup(const char* psz);    // near middle
char *uxdup(const wchar_t *pwsz);

wchar_t* uxdup(const char* psz)   // at bottom
{
   int len = strlen(psz); // or size_t len = strlen(psz) + 1;  // (line 450)
   wchar_t* pwsz = new wchar_t[len]; // no need for '+1'
   mbstowcs(pwsz, psz, len);
   return pwsz;
}

char *uxdup(const wchar_t *pwsz)
{
   int       len = wcslen(pwsz) + 1;
   char*  psz = new char[len]; // just use 'len' as calculated above, the buffer is large enough
   if (wcstombs(psz, pwsz, len) == (size_t)-1)  // (line 460)
        *psz=0;
   
   return psz;  
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(469) : error C2084: function 'wchar_t *uxdup(const char *)' already has a body
        c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(276) : see previous definition of 'uxdup'
c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(477) : error C2084: function 'char *uxdup(const wchar_t *)' already has a body
        c:\mplab\source\mcdll\pm-sdk-net\src\include\ustring.h(277) : see previous definition of 'uxdup'
jkrCommented:
Could you add some line number info to the above? 'ustring.h(469)' seems to be 'beyond' that snippet if 'line 460' is still correct.
jkrCommented:
>>LSC.obj : error LNK2005: "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z) already
>>defined in LoggedException.obj

Ag, now we got - it - you should put the function bodies in a .cpp file instead of the .h file.
jmatyasAuthor Commented:
Oh didn't see the comments on wcslen, until now.  Thanks.

Is there an advantage to having the code split in two with the function declaration and definition seperate, versus having it defined once in regards to the linking issue?  I get a linking issue when I have the subroutine defined in one place, but I get compiler messages listed above when I do try and seperate them.  


 
jkrCommented:
>>Is there an advantage to having the code split in two with the function declaration and definition seperate

Yes. You don't get the

>>LSC.obj : error LNK2005: "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z) already
>>defined in LoggedException.obj

errors any more ;o)

To explain that: When you put the implementation in a header file that is included by multiple .cpp files, the compiler will  generate the code in each .cpp file, thus causing the 'multiply' defined errors.
jmatyasAuthor Commented:
Ok.  I will put the function bodies in a .cpp file and see how that goes.
jmatyasAuthor Commented:
I created ustring.cpp with the following code in it (and removed the code from ustring.h):

#include "ustring.h"

wchar_t* uxdup(const char* psz)  
{
   size_t len = strlen(psz) + 1;
   wchar_t* pwsz = new wchar_t[len+1];
   mbstowcs(pwsz, psz, len);
   return pwsz;
}

char *uxdup(const wchar_t *pwsz)
{
   int len = wcslen(pwsz);
   char*  psz = new char[len*2+1];
   if (wcstombs(psz, pwsz, len) == (size_t)-1)
        *psz=0;
   
   return psz;  
}
jmatyasAuthor Commented:
Now I get the same errors that started this whole tread, but I think that ustring.cpp is not being linked correctly to ustring.h.

.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllCanUnloadNow' should not be assigned an ordinal
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllGetClassObject' should not be assigned an ordinal
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllRegisterServer' should not be assigned an ordinal
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllUnregisterServer' should not be assigned an ordinal
   Creating library .\..\..\bin\Release/Suite_CCSPic.lib and object .\..\..\bin\Release/Suite_CCSPic.exp
T_CCSPICcc.obj : error LNK2001: unresolved external symbol "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z)
LoggedException.obj : error LNK2019: unresolved external symbol "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z) referenced in function "public: __thiscall String816::operator char const *(void)" (??BString816@@QAEPBDXZ)
LSC.obj : error LNK2001: unresolved external symbol "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z)
S_CCSPIC.obj : error LNK2001: unresolved external symbol "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z)
Suite_CCSPic.obj : error LNK2001: unresolved external symbol "char * __cdecl uxdup(wchar_t const *)" (?uxdup@@YAPADPB_W@Z)
LSC.obj : error LNK2019: unresolved external symbol "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z) referenced in function "public: __thiscall String816::operator wchar_t const *(void)" (??BString816@@QAEPB_WXZ)
S_CCSPIC.obj : error LNK2001: unresolved external symbol "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z)
T_CCSPICcc.obj : error LNK2001: unresolved external symbol "wchar_t * __cdecl uxdup(char const *)" (?uxdup@@YAPA_WPBD@Z)
.\..\..\bin\Release/Suite_CCSPic.dll : fatal error LNK1120: 2 unresolved externals

jkrCommented:
Yup, that looks good - just add that file to your project. BTW, adding the code to any other .cpp file that already is in your project should have worked also.
jkrCommented:
Have you added the file to your project?
jmatyasAuthor Commented:
Now it is, but I receive this error message:

Compiling...
ustring.cpp
..\include\ustring.cpp(20) : fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?
Creating browse information file...
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
USTRING.CPP
=========================
#include "ustring.h"    //line 1

wchar_t* uxdup(const char* psz)  
{
   size_t len = strlen(psz) + 1;    // line 5
   wchar_t* pwsz = new wchar_t[len+1];
   mbstowcs(pwsz, psz, len);
   return pwsz;
}
                                              // line 10
char *uxdup(const wchar_t *pwsz)
{
   int len = wcslen(pwsz);
   char*  psz = new char[len*2+1];
   if (wcstombs(psz, pwsz, len) == (size_t)-1)
        *psz=0;
   
   return psz;  
}                                         // line 19
itsmeandnobodyelseCommented:
>>>> Ag, now we got - it - you should put the function bodies
>>>> in a .cpp file instead of the .h file

If you put implementation code to a header you need to make them 'inline' or the header may not be included by two cpp files or more.

It would be easiest to create a new cpp file, e. g. uxdup.cpp where you put the bodies into and add it to your project. However, it might be that such a cpp file already exists. Check the directory where ustring.h is located for cpp files. If you find an implementation of uxdup you might add that source rather than the solution above.

Regards, Alex
jkrCommented:
Just add

#include "stdafx.h"

at the top of USTRING.CPP to get rid of that error.
itsmeandnobodyelseCommented:
>>>> Suite_CCSPic.def : warning LNK4222: exported symbol 'DllCanUnloadNow'
>>>> should not be assigned an ordinal

You can get rid of that message by editing Suite_CCSPic.def and remove the lines were DllCanUnloadNow, and other Dll* functions were associated to an ordinal number.

Regards, Alex

itsmeandnobodyelseCommented:
>>>> Just add  #include "stdafx.h" at the top of USTRING.CPP to get rid of that error.

No, a better solution is to switch off Precompiled Header Option from ustring.cpp

- Right-click ustring.cpp in the project tree and choose 'Settings"
- Goto the C++ Tab
- Category is Precompiled Header
- Set the 'Not using Precompiled Header' option for ustring.cpp.

Regards, Alex
jkrCommented:
>>No, a better solution is to switch off Precompiled Header Option from ustring.cpp

That's unefficiant. You can't turn that of for a single file, only for the whole project. Even if that has changed I'd not turn that off for a single file (personal opinion)
jmatyasAuthor Commented:
Oops... I misread the header file the compiler gave an error on.
I thought it only wanted/needed "ustring.h", the same one I already included.

I added #include "stdafx.h" and it fixed the problem.
I now have a project that compiles!!  

Now if I can fix the linker warnings:
Linking...
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllCanUnloadNow' should not be assigned an ordinal
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllGetClassObject' should not be assigned an ordinal
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllRegisterServer' should not be assigned an ordinal
.\Suite_CCSPic.def : warning LNK4222: exported symbol 'DllUnregisterServer' should not be assigned an ordinal
++++++++++++++++++++++++++++++++++++++++++++++++++++
; Suite_CCSPic.def : Declares the module parameters.
========================================
LIBRARY      "Suite_CCSPic.DLL"

EXPORTS
      DllCanUnloadNow     @1 PRIVATE
      DllGetClassObject   @2 PRIVATE
      DllRegisterServer   @3 PRIVATE
      DllUnregisterServer      @4 PRIVATE


jkrCommented:
Make that read

EXPORTS
     DllCanUnloadNow
     DllGetClassObject
     DllRegisterServer
     DllUnregisterServer

and these should go away also - these exports neither need ordinals nor should they be 'private'.
jmatyasAuthor Commented:
What exactly is "Precompiled Header Option"?

Why does ustring.cpp need "stdafx.h"?
I know ustring.cpp needs "ustring.h", but why the other file.

Sorry, I am pretty new to Visual C++, even though I've used C++ in college on Solaris UNIX.   I will try "itsmeandnobodyelse" suggestion, when I get some spare time, later in the week, to see if it can be done (learning exercise).  

Thanks for your help.
itsmeandnobodyelseCommented:
>>>> You can't turn that of for a single file, only for the whole project

You are wrong! The PCH settings is available for any single cpp file.

The stdafx.cpp has a different PCH settings as well cause it creates the precompiled header. You even could have more than one PCH file.

>>>> That's unefficiant.

It's unefficiant to include full Windows and MFC API in a file that doesn't need it.

#include "ustring.h"    

wchar_t* uxdup(const char* psz)  
{
   size_t len = strlen(psz) + 1;    // line 5
   wchar_t* pwsz = new wchar_t[len+1];
   mbstowcs(pwsz, psz, len);
   return pwsz;
}

char *uxdup(const wchar_t *pwsz)
{
   int len = wcslen(pwsz);
   char*  psz = new char[len*2+1];
   if (wcstombs(psz, pwsz, len) == (size_t)-1)
        *psz=0;
   
   return psz;  
}      
                                   
That file with the PCH option switched off would compile properly.
jkrCommented:
>>What exactly is "Precompiled Header Option"?

From the docs, since they can explain that better than me just rewording it:

------------------------------------------>8-------------------------------

The Microsoft C and C++ compilers provide options for precompiling any C or C++ code—including inline code. Using this performance feature, you can compile a stable body of code, store the compiled state of the code in a file, and during subsequent compilations combine the precompiled code with code that is still under development. Each subsequent compilation is faster because the stable code does not need to be recompiled.

Visual C++ offers two ways to create and use precompiled header files:

- Use AppWizard and allow it to set default compiler options for your application.

- Set compiler options yourself, either on the command line or in the development environment (Project menu, Settings command).

With Microsoft Visual C++, you can precompile any C or C++ code; you are not limited to precompiling only header files. To precompile headers, you can choose one of two approaches:

- Automatic precompiling: Use just one option (/YX) and let the compiler decide when to create and use precompiled headers.

- Manual precompiling: Use this when you know that your source files use common sets of header files but do not include them in the same order, or when you want to include source code in your precompilation.
The first choice is quick and easy. The second requires some planning, but it offers significantly faster compilations if you precompile source code other than simple header files.

------------------------------------------>8-------------------------------

That's quite a time-saver, especially when the projects grow larger.

itsmeandnobodyelseCommented:
>>>> What exactly is "Precompiled Header Option"?

Precompiled Header Option (PCH) allows to compile a header file (and all header file included from there) separatly. Thus, all cpp files that include the standard header file don't need to compile these headers again but simply get the precompiled header code mapped to their object file.

Projects with PCH normally compile faster. If you create a Wizard project in Visual Studio you got a stdafx.h header file that includes the Windows API (windows.h) and the MFC (afx.h), that need to get compiled only once.

However, there are some disadvantages that let me switch off that option in any new project:

   - all cpp files needs to have stdafx.h include as very first include (or you get that silly compiler error)
   - so all cpp include a maximum of header files even if they don't need any Windows or MFC API.
   - if you add some more includes to stdafx.h, you need to recompile the whole project if any of these
     included headers has a change
   - dependency check didn't work properly on PCH, especially if headers were exchanged between developers.

Regards, Alex

jkrCommented:
>>   - all cpp files needs to have stdafx.h include as very first include (or you get that silly compiler error)
>>   - so all cpp include a maximum of header files even if they don't need any Windows or MFC API.

That's incorrect. You can use an empty stdafx.h, so no additional header files are processed per .cpp file. And, the file does not need to be named 'stdafx.h', that's just the default.
itsmeandnobodyelseCommented:
>>>> You can use an empty stdafx.h,

??? What is an empty header file good for? It's easier to switch off PCH than to cheat the compiler, isn't it? And I don't think stdafx.cpp will compile when including an empty header.

>>>> And, the file does not need to be named 'stdafx.h',

That's true. But that information isn't important for our case.
jmatyasAuthor Commented:
Back from lunch.  Thanks for all the feedback, I understand this a lot better.
I just rebuilt my project and modified only "Suite_CCSPic.def" by removing the ordinals and 'private'.  I receive the following warnings:

Linking...
.\Suite_CCSPic.def : warning LNK4104: export of symbol 'DllCanUnloadNow' should be PRIVATE
.\Suite_CCSPic.def : warning LNK4104: export of symbol 'DllGetClassObject' should be PRIVATE
.\Suite_CCSPic.def : warning LNK4104: export of symbol 'DllRegisterServer' should be PRIVATE
.\Suite_CCSPic.def : warning LNK4104: export of symbol 'DllUnregisterServer' should be PRIVATE
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Is this something important, or is it safe to ignore?
If I put private back into the file, I get no errors nor warnings, as follows:
++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Suite_CCSPic.def : Declares the module parameters.

LIBRARY      "Suite_CCSPic.DLL"

EXPORTS
      DllCanUnloadNow     PRIVATE
      DllGetClassObject      PRIVATE
      DllRegisterServer      PRIVATE
      DllUnregisterServer   PRIVATE

      
jkrCommented:
>>Is this something important, or is it safe to ignore?

You *could* ignore it (that wouldn't do any harm), but it seems I was wrong here:

Linker Tools Warning LNK4104
export of symbol "symbol" should be PRIVATE

This warning is emitted when you are building an import library for a DLL and export one of the above functions without specifying it as PRIVATE in the module-definition file. In general these functions are exported for use only by OLE. Placing them in the import library can lead to unusual behavior when a program linked to the library incorrectly makes calls to them.
jmatyasAuthor Commented:
Thanks for explaining that.  That sounds like what I am supposed to accomplish.  I am now having some problems creating a DLL file from my project; the project compiles and links, but I don't get a DLL file as output like I expected.  I will put this question on another thread, and close this call, since the original question has been solved.  I really appreciate the help from everybody that responded, esp. jkr and itsmeandnobodyelse.  Any feedback on this next question, please post to the new thread, so this one can be closed.  Thanks.

------ Build started: Project: Suite_CCSPic, Configuration: Release MinDependency Win32 ------
Linking...
   Creating library .\..\..\bin\Release/Suite_CCSPic.lib and object .\..\..\bin\Release/Suite_CCSPic.exp
Embedding manifest...
Performing registration
Build log was saved at "file://c:\MPLAB\Source\mcdll\pm-sdk-net\src\Suite_CCSPic\ReleaseMinDependency\BuildLog.htm"
Suite_CCSPic - 0 error(s), 0 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
jkrCommented:
Can you post the build log?
jkrCommented:
Um, I mean - can you post the build log *here* ;o)

>>please post to the new thread, so this one can be closed.

*You* will have to close this Q - please see http://www.experts-exchange.com/Community_Support/help.jsp#hs5 ("Closing Questions")
jmatyasAuthor Commented:
Sure, here is the build log (I posted here and also in the new thread):


Build Log
              

Build started: Project: Suite_CCSPic, Configuration: Release MinDependency|Win32

Command Lines
              

Creating temporary file "c:\MPLAB\Source\mcdll\pm-sdk-net\src\Suite_CCSPic\ReleaseMinDependency\RSP00000D4441980.rsp" with contents
[
/OUT:".\..\..\bin\Release/Suite_CCSPic.dll" /INCREMENTAL:NO /LIBPATH:"..\include" /DLL /MANIFEST /MANIFESTFILE:".\ReleaseMinDependency\Suite_CCSPic.dll.intermediate.manifest" /NODEFAULTLIB:"libc.lib" /NODEFAULTLIB:"libcd.lib" /NODEFAULTLIB:"libcp.lib" /DEF:".\Suite_CCSPic.def" /PDB:".\..\..\bin\Release/Suite_CCSPic.pdb" /SUBSYSTEM:WINDOWS /IMPLIB:".\..\..\bin\Release/Suite_CCSPic.lib" /MACHINE:X86 htmlhelp.lib version.lib ModuleInfo.lib shell32.lib gdi32.lib ustring.lib bsd_string.lib

".\ReleaseMinDependency\LoggedException.obj"

".\ReleaseMinDependency\LSC.obj"

".\ReleaseMinDependency\ParseMsgLine.obj"

".\ReleaseMinDependency\RegPathString.obj"

".\ReleaseMinDependency\S_CCSPIC.obj"

".\ReleaseMinDependency\S_MenuProxy2.obj"

".\ReleaseMinDependency\S_Service.obj"

".\ReleaseMinDependency\SA_CCSPIC.obj"

".\ReleaseMinDependency\StdAfx.obj"

".\ReleaseMinDependency\Suite_CCSPic.obj"

".\ReleaseMinDependency\Suite_CCSPic.res"

".\ReleaseMinDependency\T_CCSPICcc.obj"

".\ReleaseMinDependency\TA_CCSPICcc.obj"

".\ReleaseMinDependency\TA_CCSPICccPage.obj"

".\ReleaseMinDependency\TA_CCSPICPage.obj"

".\ReleaseMinDependency\Trans.obj"

".\ReleaseMinDependency\TransDesc.obj"

".\ReleaseMinDependency\TransEng.obj"

".\ReleaseMinDependency\TransSem.obj"

".\ReleaseMinDependency\ustring1.obj"
]
Creating command line "link.exe @"c:\MPLAB\Source\mcdll\pm-sdk-net\src\Suite_CCSPic\ReleaseMinDependency\RSP00000D4441980.rsp" /NOLOGO /ERRORREPORT:PROMPT"
Creating temporary file "c:\MPLAB\Source\mcdll\pm-sdk-net\src\Suite_CCSPic\ReleaseMinDependency\RSP00000E4441980.rsp" with contents
[
/outputresource:"..\..\bin\Release\Suite_CCSPic.dll;#2" /manifest

".\ReleaseMinDependency\Suite_CCSPic.dll.intermediate.manifest"
]
Creating command line "mt.exe @"c:\MPLAB\Source\mcdll\pm-sdk-net\src\Suite_CCSPic\ReleaseMinDependency\RSP00000E4441980.rsp" /nologo"
Creating temporary file "c:\MPLAB\Source\mcdll\pm-sdk-net\src\Suite_CCSPic\ReleaseMinDependency\BAT00000F4441980.bat" with contents
[
@echo Manifest resource last updated at %TIME% on %DATE% > ".\ReleaseMinDependency\mt.dep"
]
Creating command line """c:\MPLAB\Source\mcdll\pm-sdk-net\src\Suite_CCSPic\ReleaseMinDependency\BAT00000F4441980.bat"""
Creating temporary file "c:\MPLAB\Source\mcdll\pm-sdk-net\src\Suite_CCSPic\ReleaseMinDependency\BAT0000104441980.bat" with contents
[
@echo off

regsvr32 /s /c "c:\MPLAB\Source\mcdll\pm-sdk-net\bin\Release\Suite_CCSPic.dll"

echo regsvr32 exec. time > ".\..\..\bin\Release\regsvr32.trg"



if errorlevel 1 goto VCReportError

goto VCEnd

:VCReportError

echo Project : error PRJ0019: A tool returned an error code from "Performing registration"

exit 1

:VCEnd
]
Creating command line """c:\MPLAB\Source\mcdll\pm-sdk-net\src\Suite_CCSPic\ReleaseMinDependency\BAT0000104441980.bat"""

Output Window
              

Linking...
   Creating library .\..\..\bin\Release/Suite_CCSPic.lib and object .\..\..\bin\Release/Suite_CCSPic.exp
Embedding manifest...
Performing registration

Results
              

Build log was saved at "file://c:\MPLAB\Source\mcdll\pm-sdk-net\src\Suite_CCSPic\ReleaseMinDependency\BuildLog.htm"
Suite_CCSPic - 0 error(s), 0 warning(s)



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
C++

From novice to tech pro — start learning today.