We help IT Professionals succeed at work.

unresolved externals linking to gSOAP objects

softechnics
softechnics asked
on
7,433 Views
Last Modified: 2008-01-09
I've developed a stand-alone Web Service C++ client (WSClient.exe) that works. Now, I need to link the gSOAP generated oject files into a legacy C++ application. So I generate the object files as before, but do not link the objects creating an executable. Instead, I then compile and link my legacy app with the gSOAP generated objects. I get unsatisfied Link errors as follows:

(All in stdsoap2.obj):

_namespaces
___mb_cur_max
plus a couple long std:: fucntions.

I found mb_cur_max and MB_CUR_MAX in stdlib.h and included it, but the error persists. I would think the problem is that my legacy Makefile is not including an object or library that the standalone test client Makefile is including, but I cannot find it. Also, namespaces is not found in stdlib.h, but is found in a few other system includes, but none that are included in the working WS client application.

Any ideas?
Comment
Watch Question

jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Chances are that you are linking with the wrong version of the CRT (libc.lib vs. msvcrt.lib). What are your compiler and linker options?

Author

Commented:
***********************************************
* The gSOAP makefile (for the legacy system) is as follows (run first - builds the SOAP lib files and my ws client and puts in WebService.lib):
***********************************************

GSOAPDIR=gSOAP
GSOAP=$(GSOAPDIR)\soapcpp2.exe
SOAPH=$(GSOAPDIR)\stdsoap2.h
SOAPC=$(GSOAPDIR)\stdsoap2.c
SOAPCPP=$(GSOAPDIR)\stdsoap2.cpp
WSDL=USMCAccessor.wsdl
WSDL2H=wsdl2h.exe

CC=cl
CPP=cl
COFLAGS=-O2 -c
CWFLAGS=-Wall
CIFLAGS=-I..\include -I..\..\include\stutil32 -I..\.. -I$(GSOAPDIR)
CMFLAGS=-GX
CFLAGS= $(COFLAGS) $(CIFLAGS) $(CMFLAGS)

CPU = i386
PROJ = WebService

#CONSOLE_APP = 1
#GUI_APP     = 1
#DLL_APP     = 1
LIB_APP     = 1

# Define project specific macros
PROJ_OBJS  = $(CPU)\soapClient.obj $(CPU)\soapC.obj $(CPU)\stdsoap2.obj $(CPU)\WSClient.obj

BASE_OBJS  =
OBJDIR     = $(CPU)
EXTRA_LIBS = odbc32.lib odbccp32.lib wsock32.lib
GLOBAL_DEP =
RC_DEP     =
PROJ_DEP   =
INCLUDES   = $(CIFLAGS)
CDEFS      = -DWINNT
lflags     = /INCREMENTAL:NO /PDB:NONE /RELEASE /NOLOGO

!ifdef DEBUG
DEBUG_OPTS = $(ldebug) -debugtype:both
!endif

all:            WSClient $(CPU)\$(PROJ).lib      

# Build rule for WSClient header file (built by gSOAP)
WSClient.h:
                  cd $(GSOAPDIR)
                  $(WSDL2H) -c -o WSClient.h $(WSDL)
                  mv WSClient.h ..
                  cd ..

# Build rule for Web Service Client .OBJ files
WSClient:      WSClient.h WSClient.cpp $(SOAPH) $(SOAPCPP)
                  $(GSOAP) WSClient.h
                  $(CPP) $(CFLAGS) -o WSClient WSClient.cpp soapC.c soapClient.c $(SOAPCPP)
                  mv *.obj $(CPU)

# Build rule for LIB
!ifdef LIB_APP
$(CPU)\$(PROJ).lib: $(PROJ_OBJS)
  lib /OUT:$(CPU)\$(PROJ).lib $(PROJ_OBJS)
  copy $(CPU)\$(PROJ).lib ..\lib
  copy soapH.h ..\include
  copy soapStub.h ..\include
  copy $(GSOAPDIR)\stdsoap2.h ..\include
!endif

clean:
            rm -f *.o soapH.h soapStub.h soapC.cpp soapC.c soapClient.cpp soapClient.c soapServer.cpp soapServer.c soap*Proxy.h
distclean:
            rm -f *.o *.wsdl *.xsd *.xml *.nsmap *.log soapH.h soapStub.h soapC.cpp soapC.c soapClient.cpp soapClient.c soapServer.cpp soapServer.c soap*Proxy.h WSClient

**********************************
* The legacy Makefile is as follows (run second - includes WebService.lib, from above):
**********************************
!include <win32.mak>

PROJ = DBItem

CONSOLE_APP = 1
LIB_APP     = 1

# Default the CPU variable to i386 if not defined.
!ifndef CPU
CPU = i386
!endif

all: $(CPU)\$(PROJ).exe $(CPU)\$(PROJ)Hook.lib


# Define project specific macros
PROJ_OBJS  = $(CPU)\gh_Item.obj
HOOK_OBJS  = $(CPU)\gh_ItemHook.obj

BASE_OBJS  =
OBJDIR     = $(CPU)
EXTRA_LIBS = odbc32.lib odbccp32.lib wsock32.lib netapi32.lib ..\..\lib\DataBase.lib ..\..\lib\remote.lib \
             ..\..\lib\stutil32.lib ..\..\lib\sapi.lib ..\..\lib\sremote.lib \
             ..\..\lib\RapiItemSrv.lib ..\..\lib\CommonBusRule.lib ..\..\lib\DBItemHook.lib \
             ..\..\lib\DBAuthHook.lib ..\lib\WebService.lib
GLOBAL_DEP = ..\include\WSClient2.h ..\include\ItemHook.h ..\..\include\DBItem.h
RC_DEP     =
PROJ_DEP   = ..\..\lib\DataBase.lib ..\..\lib\remote.lib ..\..\lib\sapi.lib ..\..\lib\sremote.lib \
             ..\..\lib\RapiItemSrv.lib ..\..\lib\CommonBusRule.lib \
             ..\..\lib\DBItemHook.lib ..\lib\WebService.lib
INCLUDES   = -I ..\..\include\stutil32 -I ..\include -I ..\..\include -I ..\include\4690
CDEFS      = -DWINNT
lflags     = /INCREMENTAL:NO /PDB:NONE /RELEASE /NOLOGO /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcpmtd.lib /NODEFAULTLIB:libcp.lib

!ifndef NODEBUG
DEBUG_OPTS = $(ldebug) -debugtype:both
!endif


# Inference rule for updating the object files
{.}.cpp{$(OBJDIR)}.obj:
!ifdef DLL_APP
  $(cc) $(cdebug) $(cflags) $(cvarsdll) $(CDEFS) -Zp1 -GX -GF -Fo$* $(INCLUDES) $<
!else
  $(cc) $(cdebug) $(cflags) $(cvarsdll) $(CDEFS) -Zp1 -GX -GF -Fo$* $(INCLUDES) $<
!endif

# Build rule for CONSOLE EXE
!ifdef CONSOLE_APP
$(CPU)\$(PROJ).EXE: $(BASE_OBJS) $(PROJ_OBJS) $(PROJ_DEP) $(PROJ).res
    $(link) $(DEBUG_OPTS) $(conlflags) \
    /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:nafxcw.lib \
    $(BASE_OBJS) $(PROJ_OBJS) $(PROJ).res $(EXTRA_LIBS) \
    -out:$(CPU)\$(PROJ).exe $(MAPFILE)
!endif

# Build rule for LIB
!ifdef LIB_APP
$(CPU)\$(PROJ)Hook.lib: $(HOOK_OBJS)
  lib /OUT:$(CPU)\$(PROJ)Hook.lib $(HOOK_OBJS)
  copy $(CPU)\$(PROJ)Hook.lib ..\lib
!endif

jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Try to remove '/NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcpmtd.lib /NODEFAULTLIB:libcp.lib' from the 'lflags' in the legacy makefile.

Author

Commented:
I get several multiply defined errors in msvcrt.lib and libc.lib, then a message from the linker to use the /NODEFAULT option on these files. Then I get only 1 unresolved external on 'namespaces'.
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
What are the CFLAGS from your Win32.mak?

Author

Commented:
>>  What are the CFLAGS from your Win32.mak?
I'm using the default Visual Studio Win32.mak file found in the MSVC include folder.

Additional Info:

I linked with the /VERBOSE option and found the mb_cur_max defined in libc.lib, so I only removed the /NODEFAULTLIB option for that file. That took care of that unresolved, but it replaced it with another (ARGHHH!!!). Even with the VERBOSE option, I could not find where 'namespaces' was defined or being used.

The other three unresolved externals are:

WebService.lib(stdsoap2.obj) : error LNK2001: unresolved external symbol "public: static class std::locale::id std::ctype<char>::id" (?id@?$ctype@D@std@@2V0loca
le@2@A)
WebService.lib(stdsoap2.obj) : error LNK2001: unresolved external symbol "private: static int std::locale::id::_Id_cnt" (?_Id_cnt@id@locale@std@@0HA)
WebService.lib(stdsoap2.obj) : error LNK2001: unresolved external symbol "private: static short const * const std::ctype<char>::_Cltab" (?_Cltab@?$ctype@D@std@@0PBFB)
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
That is related to '/NODEFAULTLIB:libcp.lib' - these functions reside in libcp.lib

Author

Commented:
I'm pretty sure it is. But if I remove it, then I get several additional errors as a result of multiply defined variables, as follows:

libcp.lib(locale.obj) : error LNK2005: "public: __thiscall std::_Locinfo::_Locinfo(char const *)" (??0_Locinfo@std@@QAE@PBD@Z) already defined in msvcprt.lib(MSVCP60.dll)

libcp.lib(locale.obj) : error LNK2005: "public: __thiscall std::_Locinfo::~_Locinfo(void)" (??1_Locinfo@std@@QAE@XZ) already defined in msvcprt.lib(MSVCP60.dll)

libcp.lib(locale.obj) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char
,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in msvcprt.lib(MSVCP60.dll)

libcp.lib(locale0.obj) : error LNK2005: "public: class std::locale::facet const* __thiscall std::locale::_Getfacet(unsigned int,bool)const " (?_Getfacet@locale
@std@@QBEPBVfacet@12@I_N@Z) already defined in msvcprt.lib(MSVCP60.dll)libcp.lib(locale0.obj) : error LNK2005: "public: bool __thiscall std::locale::_I
scloc(void)const " (?_Iscloc@locale@std@@QBE_NXZ) already defined in msvcprt.lib(MSVCP60.dll)

libcp.lib(locale0.obj) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<cha
r,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined inmsvcprt.lib(MSVCP60.dll)

libcp.lib(wlocale.obj) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<cha
r,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined inmsvcprt.lib(MSVCP60.dll)

libcp.lib(xlocale.obj) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<cha
r,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined inmsvcprt.lib(MSVCP60.dll)

libcp.lib(string.obj) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char
,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in msvcprt.lib(MSVCP60.dll)

libc.lib(crt0dat.obj) : error LNK2005: _exit already defined in msvcrt.lib(MSVCRT.dll)
libc.lib(crt0dat.obj) : error LNK2005: __exit already defined in msvcrt.lib(MSVCRT.dll)
libc.lib(crt0init.obj) : error LNK2005: ___xc_z already defined in msvcrt.lib(cinitexe.obj)
libc.lib(crt0init.obj) : error LNK2005: ___xc_a already defined in msvcrt.lib(cinitexe.obj)
libc.lib(crt0init.obj) : error LNK2005: ___xi_z already defined in msvcrt.lib(cinitexe.obj)
libc.lib(crt0init.obj) : error LNK2005: ___xi_a already defined in msvcrt.lib(cinitexe.obj)

LINK : warning LNK4098: defaultlib "msvcrt.lib" conflicts with use of other libs; use /NODEFAULTLIB:library

LINK : warning LNK4098: defaultlib "libc.lib" conflicts with use of other libs;use /NODEFAULTLIB:library

WebService.lib(stdsoap2.obj) : error LNK2001: unresolved external symbol _namespaces

i386\DBItem.exe : fatal error LNK1120: 1 unresolved externals

Damned if I do, damned if I don't. In this case, three of the four unresolveds go away, only to be replaced by a bunch of multiply defineds.
CERTIFIED EXPERT
Top Expert 2012
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
PROGRESS!

I found that if I compile stdsoap2.cpp with -DWITH_NONAMESPACE, this resolves the "unresolved _namespaces" error.
I also must have the /NODEFAULTLIB:libc link flag set to resolve the 'mb_cur_max' undefined error.

Author

Commented:
I'm down to several multiply defined errors, but I believe they can all be summed up as follows:

libcp.lib(string.obj) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char
,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in msvcprt.lib(MSVCP60.dll)

libc.lib(crt0dat.obj) : error LNK2005: _exit already defined in msvcrt.lib(MSVCRT.dll)

My link command looks like this:

link -debug:full -debugtype:cv -debugtype:both /INCREMENTAL:NO /PDB:NONE /RELEASE /NOLOGO /NODEFAULTLIB:libcpmtd.lib -subsystem:console,4.0  /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:nafxcw.lib   i386\gh_Item.obj DBItem.res odbc32.lib odbccp32.lib wsock32.lib netapi32.lib ..\..\lib\DataBase.lib ..\..\lib\remote.lib  ..\..\lib\stutil32.lib ..\..\lib\sapi.lib ..\..\lib\sremote.lib  ..\..\lib\RapiItemSrv.lib ..\..\lib\CommonBusRule.lib ..\..\lib\DBItemHook.lib  ..\..\lib\DBAuthHook.lib ..\lib\WebService.lib ws2_32.lib  -out:i386\DBItem.exe

What next? ( I knew there was a good reason I deserted the C/C++ ship 10 years ago before getting into Windows programming for a reason. :-) )

Author

Commented:
EUREKA!

Finally got a good build. The last problem was resolved by placing the -MD flag in the CFLAGS list in my WebService makefile.

I appreciate your patience and assistance in helping me struggle through this quagmire of libraries. Thanks.
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Great that you found it. Sorry for not responding earlier, but there's a life without computers also ;o)
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.