Jump to content

Confusing Linker Errors

- - - - -

  • Please log in to reply
9 replies to this topic

#1
hetra

hetra

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 297 posts
  • Location:Australia
  • Programming Language:C, C++, PHP, Python, Delphi/Object Pascal, Assembly
  • Learning:Python, Assembly
Hello all,

I'm starting a simple program that uses Winsock and after I set up the simple functions VC++2010 throws Linker errors.

1>------ Build started: Project: Barbados++, Configuration: Debug Win32 ------1>  server.cpp
1>  Generating Code...
1>  Skipping... (no relevant changes detected)
1>  client.cpp
1>server.obj : error LNK2005: "int __cdecl init(void)" (?init@@YAHXZ) already defined in client.obj
1>server.obj : error LNK2005: _main already defined in client.obj
1>client.obj : error LNK2019: unresolved external symbol __imp__WSACleanup@0 referenced in function _main
1>server.obj : error LNK2001: unresolved external symbol __imp__WSACleanup@0
1>client.obj : error LNK2019: unresolved external symbol __imp__WSAStartup@8 referenced in function _main
1>server.obj : error LNK2001: unresolved external symbol __imp__WSAStartup@8
1>MSVCRTD.lib(crtexew.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========



I think that after the @ is the address (from some MSDN documentation I read a while ago).

This is the code:

client.cpp:

//client.cpp
#include "api.h"


int main(void)
{
    const int iReqWinsockVer = 2;   // Minimum winsock version required


    WSADATA wsaData;


    if(WSAStartup(MAKEWORD(iReqWinsockVer,0), &wsaData)==0)
    {
        // Check if major version is at least iReqWinsockVer
        if(LOBYTE(wsaData.wVersion) >= iReqWinsockVer)
        {
            /* ------- Call winsock functions here ------- */
        }
        else
        {
            // Required version not available
        }


        // Cleanup winsock
        if(WSACleanup() != 0)
        {
            // cleanup failed
        }
    }
    else
    {
        //  startup failed
    }
}

server.cpp:

//server.cpp
#include "api.h"
int main(void)
{
    const int iReqWinsockVer = 2;   // Minimum winsock version required


    WSADATA wsaData;


    if(WSAStartup(MAKEWORD(iReqWinsockVer,0), &wsaData)==0)
    {
        // Check if major version is at least iReqWinsockVer
        if(LOBYTE(wsaData.wVersion) >= iReqWinsockVer)
        {
            /* ------- Call winsock functions here ------- */


        }
        else
        {
            // Required version not available
        }


        // Cleanup winsock
        if(WSACleanup() != 0)
        {
            // cleanup failed
        }
    }
    else
    {
        //  startup failed
    }
}

api.h:

//api.h
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <WinSock2.h>
#include <Windows.h>
using namespace std;


int init(void)
{
    //Startup processes and such...


    return 0;
}

Probably me with my lack of experience with such Linker errors, but any help would be great.

Thanks,
Jack
Creator, Owner, Webmaster
Brezerd.net

#2
Ancient Dragon

Ancient Dragon

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 400 posts
Those errors are telling you that you need to link your program with a library. In this case you need to link with ws2_32.lib.

There are two ways to do that
1) use a pragma. Put this near the top of the *.cpp file, somewhere after the includes
[icode]#pragma comment(lib,"ws2_32.lib") [/icode]

2) Go to menu Project --> Properties (at the bottom of the list) -->
Configuration Properties --> Linker --> Input --> Add Additional Dependencies
Visit Grandpa's Forums, a social networking forum, with family-oriented arcade games, blogs, discussion forums, and photo albums.

#3
DRK

DRK

    Newbie

  • Members
  • PipPip
  • 10 posts
1. client.cpp and server.cpp should be in different projects, otherwise you have more than one main() function which is an error.
2. In your api.h header file you should move body of init() to source file, e.g. api.cpp.
3. Start api.h with
#ifndef _API_H_
#define _API_H_
and end it with
#endif


#4
hetra

hetra

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 297 posts
  • Location:Australia
  • Programming Language:C, C++, PHP, Python, Delphi/Object Pascal, Assembly
  • Learning:Python, Assembly

Quote

1) use a pragma. Put this near the top of the *.cpp file, somewhere after the includes #pragma comment(lib,"ws2_32.lib")

Thanks I forgot all about that.

Quote

client.cpp and server.cpp should be in different projects, otherwise you have more than one main() function which is an error.

Is there a way I could have them both in one solution, or make two different ones?
Jack
Creator, Owner, Webmaster
Brezerd.net

#5
Flying Dutchman

Flying Dutchman

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 889 posts
  • Location:::1
You could have both in same solution, but you should add a button or something to choose whether you want to start a server or client when you run the app.
A conclusion is where you got tired of thinking.
#define class struct    // All is public.

#6
RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Members
  • PipPipPipPipPipPipPipPip
  • 1,254 posts
  • Location:C:\Countries\US

Ancient Dragon said:

#pragma comment(lib,"ws2_32.lib")

That's universal C, or just for Visual Studio?

* * *

Hunter100 said:

Is there a way I could have them both in one solution, or make two different ones?

Sure; I'd try renaming the main () in client.cpp to client_main () (or something ...), and renaming the main () in server.cpp to server_main (). Then making a new main () that somehow gets input from the user (eg command line arguments, input field, etc.), and either calls client_main () or server_main (), based on the user input. If no user input, just displaying the command line usage, so the user can learn to use the program, would be an idea.

#7
Ancient Dragon

Ancient Dragon

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 400 posts

RhetoricalRuvim said:

That's universal C, or just for Visual Studio?
There are no universal pragmas, they are all compiler dependent.

RhetoricalRuvim said:

Sure; I'd try renaming the main () in client.cpp to client_main () (or something ...), and renaming the main () in server.cpp to server_main (). Then making a new main () that somehow gets input from the user (eg command line arguments, input field, etc.), and either calls client_main () or server_main (), based on the user input. If no user input, just displaying the command line usage, so the user can learn to use the program, would be an idea.

VC++ solutions is a collection of individual programs, each with a main() or WinMain() function. To do that you first create an empty solution, then add two projects, one for client and the other for server. Each project is compiled and linked as separate programs, they just happen to have a common solution file to make it easier to manage from within vc++ 2010 IDE.
Visit Grandpa's Forums, a social networking forum, with family-oriented arcade games, blogs, discussion forums, and photo albums.

#8
hetra

hetra

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 297 posts
  • Location:Australia
  • Programming Language:C, C++, PHP, Python, Delphi/Object Pascal, Assembly
  • Learning:Python, Assembly
1>------ Build started: Project: Server, Configuration: Debug Win32 ------
2>------ Build started: Project: Client, Configuration: Debug Win32 ------
2>  client.cpp
1>  server.cpp
1>MSVCRTD.lib(crtexew.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup
1>D:\Barbados++\Output\Barbados++\Debug\Server.exe : fatal error LNK1120: 1 unresolved externals
2>MSVCRTD.lib(crtexew.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup
2>D:\Barbados++\Output\Barbados++\Debug\Client.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 2 failed, 0 up-to-date, 0 skipped ==========



All I did was add the pragma line. At least there's less errors now.
Jack
Creator, Owner, Webmaster
Brezerd.net

#9
RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Members
  • PipPipPipPipPipPipPipPip
  • 1,254 posts
  • Location:C:\Countries\US
/* @Hunter100: */ It looks to me like it's looking for a WinMain () function. Would it work if you add one in?

#10
Flying Dutchman

Flying Dutchman

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 889 posts
  • Location:::1
According to this, you created wrong project type.
A conclusion is where you got tired of thinking.
#define class struct    // All is public.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users