?
Solved

unresolved externals linking to gSOAP objects

Posted on 2006-03-27
13
Medium Priority
?
6,923 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?
0
Comment
Question by:softechnics
  • 7
  • 6
13 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 16303457
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?
0
 

Author Comment

by:softechnics
ID: 16303544
***********************************************
* 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

0
 
LVL 86

Expert Comment

by:jkr
ID: 16303590
Try to remove '/NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcpmtd.lib /NODEFAULTLIB:libcp.lib' from the 'lflags' in the legacy makefile.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:softechnics
ID: 16303689
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'.
0
 
LVL 86

Expert Comment

by:jkr
ID: 16303831
What are the CFLAGS from your Win32.mak?
0
 

Author Comment

by:softechnics
ID: 16304648
>>  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)
0
 
LVL 86

Expert Comment

by:jkr
ID: 16304788
That is related to '/NODEFAULTLIB:libcp.lib' - these functions reside in libcp.lib
0
 

Author Comment

by:softechnics
ID: 16311407
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.
0
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 16312789
You should remove the references to msvc(p)rt.lib - either these of libc(p).lib, both won't work.
0
 

Author Comment

by:softechnics
ID: 16313766
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.
0
 

Author Comment

by:softechnics
ID: 16314370
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. :-) )
0
 

Author Comment

by:softechnics
ID: 16314927
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.
0
 
LVL 86

Expert Comment

by:jkr
ID: 16317682
Great that you found it. Sorry for not responding earlier, but there's a life without computers also ;o)
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
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.
Suggested Courses

862 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