We help IT Professionals succeed at work.

C to C++ error message (Method does not take three arguments)

newpro2010
newpro2010 used Ask the Experts™
on
Here is a C code that I have tried to modify a bit in order to compile it in my C++ application.
When I compile I get this error message:

1>  All outputs are up-to-date.
1>AdvanceAdapter.obj : error LNK2019: unresolved external symbol __imp__getnameinfo@28 referenced in function "char * __cdecl ip6tos(struct sockaddr *,char *,int)" (?ip6tos@@YAPADPAUsockaddr@@PADH@Z)
1>...\Visual Studio 2010\Projects\Final\Debug\Final.exe : fatal error LNK1120: 1 unresolved externals
1>
1>Build FAILED.

I would appreciate any comment
((((AdvanceAdapter.cpp))))

#include "stdafx.h"
#include <pcap.h>
#include "AdvanceAdapter.h"

#include <stdio.h>



#ifndef WIN32
    #include <sys/socket.h>
    #include <netinet/in.h>
#else
    #include <winsock.h>
#endif

// Function prototypes
void ifprint(pcap_if_t *d);
char *iptos(u_long in);
char *ip6tos(struct sockaddr *sockaddr, char *address, int addrlen);

AdvanceAdapter::AdvanceAdapter()
	{
	}

AdvanceAdapter::~AdvanceAdapter()
	{
	} 
	
	int AdvanceAdapter::ObtainAdvanceInfo()
	{

    pcap_if_t *alldevs;
  pcap_if_t *d;
  char errbuf[PCAP_ERRBUF_SIZE+1];
  char source[PCAP_ERRBUF_SIZE+1];

  printf("Enter the device you want to list:\n"
            "rpcap://              ==> lists interfaces in the local machine\n"
            "rpcap://hostname:port ==> lists interfaces in a remote machine\n"
            "                          (rpcapd daemon must be up and running\n"
            "                           and it must accept 'null' authentication)\n"
            "file://foldername     ==> lists all pcap files in the give folder\n\n"
            "Enter your choice: ");

  fgets(source, PCAP_ERRBUF_SIZE, stdin);
  source[PCAP_ERRBUF_SIZE] = '\0';

  /* Retrieve the interfaces list */
  if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1)
  {
    fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
    exit(1);
  }

  /* Scan the list printing every entry */
  for(d=alldevs;d;d=d->next)
  {
    ifprint(d);
  }

  pcap_freealldevs(alldevs);

  return 1;
}



/* Print all the available information on the given interface */
void ifprint(pcap_if_t *d)
{
  pcap_addr_t *a;
  char ip6str[128];

  /* Name */
  printf("%s\n",d->name);

  /* Description */
  if (d->description)
    printf("\tDescription: %s\n",d->description);

  /* Loopback Address*/
  printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");

  /* IP addresses */
  for(a=d->addresses;a;a=a->next) {
    printf("\tAddress Family: #%d\n",a->addr->sa_family);
  
    switch(a->addr->sa_family)
    {
      case AF_INET:
        printf("\tAddress Family Name: AF_INET\n");
        if (a->addr)
          printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
        if (a->netmask)
          printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
        if (a->broadaddr)
          printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
        if (a->dstaddr)
          printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
        break;

      case AF_INET6:
        printf("\tAddress Family Name: AF_INET6\n");
        if (a->addr)
          printf("\tAddress: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str)));
       break;

      default:
        printf("\tAddress Family Name: Unknown\n");
        break;
    }
  }
  printf("\n");
}



/* From tcptraceroute, convert a numeric IP address to a string */
#define IPTOSBUFFERS    12
char *iptos(u_long in)
{
    static char output[IPTOSBUFFERS][3*4+3+1];
    static short which;
    u_char *p;

    p = (u_char *)&in;
    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
    _snprintf_s(output[which], sizeof(output[which]), sizeof(output[which]),"%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
    return output[which];
}

char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)
{
    socklen_t sockaddrlen;

    #ifdef WIN32
    sockaddrlen = sizeof(struct sockaddr_in6);
    #else
    sockaddrlen = sizeof(struct sockaddr_storage);
    #endif


    if(getnameinfo(sockaddr, 
        sockaddrlen, 
        address, 
        addrlen, 
        NULL, 
        0, 
        NI_NUMERICHOST) != 0) address = NULL;

    return address;
}
.......................................................................................
.......................................................................................

((((AdvanceAdapter.h))))

#include "stdafx.h"
#include <iostream>
#ifndef ADVANCEADAPTER_H
#define ADVANCEADAPTER_H

class AdvanceAdapter {

public:
	// Function prototypes
	AdvanceAdapter(); //Constructor
	~AdvanceAdapter();//destructor

	int ObtainAdvanceInfo(); //the function


};

#endif 

......................................................................................
......................................................................................

((((Final.cpp)))

#include "stdafx.h"
#include <iostream>
#include "Adapters.h"
#include "ListenToAdapter.h"
#include "AdvanceAdapter.h"


using namespace std;

Adapters *Adapt;
ListenToAdapter *List;
AdvanceAdapter *Obtain;



int main ()


{
	
	cout << "For checking the adapters available press 1 \n";
	cout << "For listening to a specific adapter please press the number of that adapter \n";
	
	int choice = 0;
	cin >> choice;

	switch (choice)
	{
	case 1:
		
	Adapt = new Adapters();

	
	Adapt->displayAdapters();
	
	delete Adapt;

	case 2:
		List = new ListenToAdapter();
		List->listen();
		delete List;

	case 3:

		Obtain = new AdvanceAdapter();
		Obtain->ObtainAdvanceInfo();
		delete Obtain;

	}
	
	

	
}

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Hi newpro2010,

the error message tells that the linker cannot find the function 'getnameinfo' used in 'ip6tos' - I guess it's about the WinSocket function 'getnameinfo', so it should be ok to link your application against 'Ws2_32.lib' - a simple way to do so is to add this line in your code:
#pragma comment ( lib, "Ws2_32.lib" )

Open in new window

Hope this helps,

ZOPPO

masheikSoftware Engineer
Commented:
Hi,

 Did you add all the linker libraries in to the visual studio project solution properly,
 Project ->Right click-->Properties-->Linker --> input --> Additional include directories --> ws2_32.lib
eevs9.jpg
Top Expert 2016
Commented:
the ws2_32.lib is an import lib for the ws2_32.dll. i would prefer to add the lib to the project properties as masheik has suggested cause for later maintenance you rarely would search for pragma statements in the sources when looking for a linker issue.

a 3rd way is to add the ws2_32.lib into the project tree.

Sara

Author

Commented:
I've requested that this question be deleted for the following reason:

I have solved the problem. I had to change the parameters
masheikSoftware Engineer

Commented:
The same answers recommended by 3 experts.
Top Expert 2016

Commented:
masheik is right. any of the three answers would have solved the original question.

so in my opinion the question should not be deleted and the answers should be honored.

Sara
masheikSoftware Engineer

Commented:
It is supposed to be split between all of them masheik,sara,zoppo, because all of them giving different way to solve the problem
I agree ...
Top Expert 2016

Commented:
as already told, any of the comments is a valid solution.

masheik's suggestion is the standard way and it should get points.

Sara

Author

Commented:
Good, I'm happy for that..
There was no option to re-award, so thank you :)