Passing arguments to main function in C++

newpro2010
newpro2010 used Ask the Experts™
on

Hello,
I have my own application and I need to insert this code in a saparate class and call it from my own main function.
The problem that I am facing is when I change this main function into another and try to call it from my main function I get a bunch of error messages, mainly becuase of the argument passing (I think)

Any suggestions?
#include "stdafx.h"
#include "pcap.h"

/* prototype of the packet handler */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);

int main(int argc, char **argv)
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_dumper_t *dumpfile;

struct pcap_pkthdr *header;
const u_char *pkt_data;
int res;
pcap_t *fp;
    
    /* Check command line */
    if(argc != 2)
    {
        printf("usage: %s filename", argv[0]);
        return -1;
    }
    
    /* Retrieve the device list on the local machine */
    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
    {
        fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
        exit(1);
    }
    
    /* Print the list */
    for(d=alldevs; d; d=d->next)
    {
        printf("%d. %s", ++i, d->name);
        if (d->description)
            printf(" (%s)\n", d->description);
        else
            printf(" (No description available)\n");
    }

    if(i==0)
    {
        printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
        return -1;
    }
    
    printf("Enter the interface number (1-%d):",i);
    scanf_s("%d", &inum);
    
    if(inum < 1 || inum > i)
    {
        printf("\nInterface number out of range.\n");
        /* Free the device list */
        pcap_freealldevs(alldevs);

		return -1;
    }
        
    /* Jump to the selected adapter */
    for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
    
    
    /* Open the device */
    if ( (adhandle= pcap_open(d->name,          // name of the device
                              65536,            // portion of the packet to capture
                                                // 65536 guarantees that the whole packet will be captured on all the link layers
                              PCAP_OPENFLAG_PROMISCUOUS,    // promiscuous mode
                              1000,             // read timeout
                              NULL,             // authentication on the remote machine
                              errbuf            // error buffer
                              ) ) == NULL)
    {
        fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
        /* Free the device list */
        pcap_freealldevs(alldevs);
        return -1;
    }

    /* Open the dump file */
    dumpfile = pcap_dump_open(adhandle, argv[1] ); //adhandle, argv[1]

    if(dumpfile==NULL)
    {
        fprintf(stderr,"\nError opening output file\n");
        return -1;
    }
    
    printf("\nlistening on %s... Press Ctrl+C to stop...\n", d->description);
    
    /* At this point, we no longer need the device list. Free it */
    pcap_freealldevs(alldevs);
    
    /* start the capture */
    pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile);

    /* while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0)
    {
	pcap_dump((unsigned char *) dumpfile, header, pkt_data);
	 }
	*/
    return 0;
}


// Callback function invoked by libpcap for every incoming packet 
void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
    // save the packet on the dump file 
    pcap_dump(dumpfile, header, pkt_data);
}

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
AndyAinscowFreelance programmer / Consultant

Commented:
Showing the errors would be useful.

do you mean something like this?

#include "stdafx.h"
#include "pcap.h"

/* prototype of the packet handler */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);

//prototype of the new function
int foo(int argc, char **argv);


int main(int argc, char **argv)
{
  return foo(argc, argv);
}

int foo()
{
....  your code from main goes here

Open in new window

Author

Commented:
Hello AndyAniscow,

Thanks for the fast reply.. Here is the complete code:

Every time I change the arguments or the call I get a different error message. but mainly ((function can not take 0 arguments))

I've started to learn C++ recently :)

Thanks in advance
(((CreatingDumpFile.cpp)))

#include "stdafx.h"
#include "pcap.h"
#include "CreatingDumpFile.h"

using namespace std;

// prototype of the packet handler
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
int CreatDump (int argc, char **argv);

        CreatingDumpFile::CreatingDumpFile()
	{
	}

	CreatingDumpFile::~CreatingDumpFile()
	{
	} 

	int CreatingDumpFile::UsingCreatDump()
	{
        CreatDump();
        return 0;
	}

	int argc;
	char **argv;

int CreatDump () /*this was the main method, I'm trying to call it from UsingCreatDump, and then call the later one from my main method in Final.cpp */
	{
	//int argc;
	//char **argv;
 pcap_if_t *alldevs;
 pcap_if_t *d;
 int inum;
 int i=0;
 pcap_t *adhandle;
 char errbuf[PCAP_ERRBUF_SIZE];
 pcap_dumper_t *dumpfile;

 struct pcap_pkthdr *header;
 const u_char *pkt_data;
 int res;
 pcap_t *fp;
    
    /* Check command line */
    if(argc != 2)
    {
        printf("usage: %s filename", argv[0]);
        return -1;
    }
    
    /* Retrieve the device list on the local machine */
    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
    {
        fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
        exit(1);
    }
    
    /* Print the list */
    for(d=alldevs; d; d=d->next)
    {
        printf("%d. %s", ++i, d->name);
        if (d->description)
            printf(" (%s)\n", d->description);
        else
            printf(" (No description available)\n");
    }

    if(i==0)
    {
        printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
        return -1;
    }
    
    printf("Enter the interface number (1-%d):",i);
    scanf_s("%d", &inum);
    
    if(inum < 1 || inum > i)
    {
        printf("\nInterface number out of range.\n");
        /* Free the device list */
        pcap_freealldevs(alldevs);

		return -1;
    }
        
    /* Jump to the selected adapter */
    for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
    
    
    /* Open the device */
    if ( (adhandle= pcap_open(d->name,          // name of the device
                              65536,            // portion of the packet to capture
                                                // 65536 guarantees that the whole packet will be captured on all the link layers
                              PCAP_OPENFLAG_PROMISCUOUS,    // promiscuous mode
                              1000,             // read timeout
                              NULL,             // authentication on the remote machine
                              errbuf            // error buffer
                              ) ) == NULL)
    {
        fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
        /* Free the device list */
        pcap_freealldevs(alldevs);
        return -1;
    }

    /* Open the dump file */
    dumpfile = pcap_dump_open(adhandle, argv[1] ); //adhandle, argv[1]

    if(dumpfile==NULL)
    {
        fprintf(stderr,"\nError opening output file\n");
        return -1;
    }
    
    printf("\nlistening on %s... Press Ctrl+C to stop...\n", d->description);
    
    /* At this point, we no longer need the device list. Free it */
    pcap_freealldevs(alldevs);
    
    /* start the capture */
    pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile);

    /* while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0)
    {
	pcap_dump((unsigned char *) dumpfile, header, pkt_data);
	 }
	*/
    return 0;
}


// Callback function invoked by libpcap for every incoming packet 
void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
    // save the packet on the dump file 
    pcap_dump(dumpfile, header, pkt_data);
} 

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

(((CreatingDumpFile.h)))

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

class CreatingDumpFile {
public:
	CreatingDumpFile(); //Constructor
	~CreatingDumpFile();//destructor
	int UsingCreatDump();

};

#endif 

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

(((Final.cpp)))

#include "CreatingDumpFile.h"

.............
........
....
.. //switch function, then in case 5:

	case 5:
		Dumping = new CreatingDumpFile();
		Dumping->UsingCreatDump();
		//delete Dumping;

Open in new window

ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
int CreatDump (int argc, char **argv);

int CreatDump ()


your prototype and declaration are inconsistent.
decide which way you want to do it.



AndyAinscowFreelance programmer / Consultant

Commented:
CreatingDumpFile::CreatingDumpFile()

You use that sort of coding when you are writing the function CreatingDumpFile that is a member of a class CreatingDumpFile.  (This is specifically a constructor when the function anme is the same as a class name).

Author

Commented:
I went with the second one (no arguments), but the application crashes :)

Access violation reading location 0x000000000.
when I set a breakpoint I can see that the application stops here:
  printf("usage: %s filename", argv[0]);
ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
Where was argv declared, and how was argv[0] set?
AndyAinscowFreelance programmer / Consultant

Commented:
I think you first need to sit down with pencil and paper and decide what needs to be the logic of your code.  Then you can start writing the crude outline of what each function should do and what it needs to be able to accomplish that task.

Author

Commented:
I went to project properties>>Configuration Properties >> Debugging
I have set the Command arguments to "save" .. which is a name to the dump file that will be created

Author

Commented:
The code that I have posted already works just fine.. I have tested it with the debugging settings that I have mentioned above.. but the problems comes when I try to make it as a class and call it from my main function
AndyAinscowFreelance programmer / Consultant

Commented:
lines 27 and 28 - you declare variables global to the file, then attempt to use them without actually giving them any values first hence the crash.

As I said before - you do not have the logic sorted out of what you want to do.  That is the foundation you write the code on and must be sorted out first.
Top Expert 2016
Commented:
first, i strongly want to support Andy with his suggestion to first try to understand what a program, class or function is supposed to do before writing code or before adopting existing code.

second, i want to add some explanations why your current code crashes.

int argc;
char **argv;

Open in new window


those are global variables cause they are outside of any class or function scope. those variables were not initialized (but in debug build the compiler made them zero).

printf("usage: %s filename", argv[0]);

Open in new window


that is the statement that crashes because of not providing properly initialized values for argc and argv.

argv is 0 (or NULL or 0x0000000 whatever you like better) and then argv[0] would try to dereference a null pointer what gives access violation.

the main function which worked before expected an argc (== count of arguments) of 2 what means it expects that beside of the name of the executable itself - what always is passed to main function as argv[0] - it additionally needs a filename to be passed as second argument. by ignoring the two arguments in your function you run into a code which assumes that the argc is at least 1 and that the argv points to a valid char* array where at least the first element argv[0] is valid. but in your case the argv is NULL and the printf crashes when trying to access argv[0].

to repair that you should remove the argc and argv competely cause they don't make sense for your scenario and call the CreatDump with the filename where it should dump to. you need a prototype 'int CreatDump(char* dumpfilename);' for that, and then could call the CreateDump like

char dumpfilename[MAX_PATH] = "c:\\temp\\my.dmp";
CreateDump(dumpfilename);

Open in new window


then remove the block where argv is checked with 'if(argc != 2)' cause that was only needed for a main function and replace the argv[1] in the call to pcap_dump_open by dumpfilename.

Sara

Top Expert 2016

Commented:
i don't know where you got that old c code, but i don't think it makes sense to make a c++ class wrapper around it. you don't get any c++ advantage by that and still have all c disadvantages like unitialized variables, pointer management, ancient runtime api, and more.  

Sara

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial