PDA

View Full Version : errore lnk2019 visual studio


pocho183
14-03-2013, 22:00
Dopo aver compilato il programma ottengo questo errore:


error LNK2019: riferimento al simbolo esterno "void __cdecl startServer(char * *)" (?startServer@@YAXPAPAD@Z) non risolto nella funzione _main


Nel file chiamato server.cpp in cui c'è L' int main(int argc, char** argv){ ecc. ad un certo punto chiamo la funzione
if(opzione==2) startServer(argv);

Quella funzione è in un file startServer.cpp che inizia con: void startServer(int argc, char**argv){

Non riesco a capire l'errore, mi sono perso con i puntatori su argv, potete aiutarmi?

tomminno
14-03-2013, 22:54
Dopo aver compilato il programma ottengo questo errore:


error LNK2019: riferimento al simbolo esterno "void __cdecl startServer(char * *)" (?startServer@@YAXPAPAD@Z) non risolto nella funzione _main


Nel file chiamato server.cpp in cui c'è L' int main(int argc, char** argv){ ecc. ad un certo punto chiamo la funzione
if(opzione==2) startServer(argv);

Quella funzione è in un file startServer.cpp che inizia con: void startServer(int argc, char**argv){

Non riesco a capire l'errore, mi sono perso con i puntatori su argv, potete aiutarmi?

Ma nel codice passi solo argv mentre la firma del metodo ha 2 parametri, la firma del metodo dovrebbe essere:
void startServer(char**argv)

lorenzo001
14-03-2013, 23:03
if(opzione==2) startServer(argc, argv);

pocho183
14-03-2013, 23:06
passando solamente char**argv, mi da errore per la mancanza di argc,perchè mi serve dopo. Come posso risolvere?

pocho183
14-03-2013, 23:09
come dice lorenzo0001 mi da errore: la funzione startserver non accetta due argomenti
l'argomento di tipo int è incompatibile con char**

lorenzo001
14-03-2013, 23:11
Non ti sei spiegato ... hai detto che hai un file .cpp in cui c'è la funzione

void startServer(int argc, char**argv)

oppure ho capito male?

Spiegati meglio.

pocho183
14-03-2013, 23:15
* Server.c */

#include "macro.h"
#include "manutenzione.h"
#include "startServer.h"
#include "funzioniServer.h"


int modalita(){

int modalita;
int testscanf;

/* Seleziono l'opzione desiderata scartando quelle "illegali" */
printf("Premi l'opzione desiderata: 1[Manutenzione], 2[Avvia server], 3 [Esci]");
testscanf = scanf("%d", &modalita); // il valore di modalità viene letto da scanf e lo inserisco in testscanf
if(testscanf == 0 || modalita>3 || modalita<1) { // Ho scelto un'opzione "illegale"
printf("\nErrore scanf\n");
chiusuraServer();
}
printf("Opzione non valida...\n");
fflush(stdout);

/* Ritorno il valore dell'opzione selezionata*/
return modalita;
}


void inizializzazione(){
printf("\nInizializzazione server in corso...\n\n");

/* Testo l'apertura del file ElencoTelefonico.txt in lettura */

if(( ElencoTelefonico = fopen("ElencoTelefonico.txt", "r")) == NULL){
printf("Non è possibile aprire il file di lettura Elenco telefonico\n\n");
fflush(stdout);
chiusuraServer();
}
else{
printf("Apertura elenco telefonico avvenuta con successo...\n");
fflush(stdout);
}

/* Testo l'apertura del file Permessi.txt in lettura */

if(( Permessi = fopen("Permessi.txt", "r")) == NULL){
printf("Non è possibile aprire il file di lettura Permessi\n\n");
chiusuraServer();
}
else{
printf("Apertura elenco utenti avvenuta con successo...\n\n");
}
}

int main(int argc, char** argv){

if(argc != 3){
printf("ERRORE - Avviare il programma usando il comando: %s [Indirizzo IP] [Porta]", argv[0]);
chiusuraServer();
}
else{

/* Eseguo il test degli archivi */

inizializzazione();
int opzione;
while(1){

/* Seleziono l'opzione dal menù principale*/

opzione = modalita();

/* Chiamo la funzione specifica per l'opzione selezionata */

if(opzione==1) manutenzioneMain();
if(opzione==2) startServer(argv);
if(opzione==3) chiusuraServer();
}
}
}






questa è la funzione


/* Server.c */

#include "macro.h"
#include "startServer.h"
#include "funzioniServer.h"
#include <winsock.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib") // Risolve problemi con il Linker tipo LNK2019.
#define LISTENQ (1024)
#define MAX_LINE (1000)

int ParseCmdLine(int argc, char *argv[], char **szPort); ////controlla se i parametri passati nel main siano corretti, szport mi indica che devo passare solo la porta da prompt,viene aggiornata dopo l'esecuzione del parse.


void startServer(int argc, char**argv){
printf("\n\nAvvio server in corso...\n");
struct sockaddr_in target;
struct sockaddr_in accepted;
short int port; /* port number */
char *endptr; /* for strtol() */
int acceptedLen= sizeof(accepted); // accept scriverà la propria taglia
char buffer[MAX_LINE]; /* character buffer */
WSADATA wsaData;

/* Get command line arguments */

ParseCmdLine(argc, argv, &endptr);// e' una funzione
port = strtol(endptr, &endptr, 0);////permette di convertire una stringa in un intero lungo,accetta dati in numero basi diverse e converte in decimale
if ( *endptr )
{
fprintf(stderr, "server: porta non riconosciuta.\n");
exit(EXIT_FAILURE);
}
printf("Server in ascolto sulla porta %d\n",port);

if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0) { // Affinchè, windows utilizzi i socket devo mandare in startup il layer dei socket
printf("errore in WSAStartup()\n");
exit(EXIT_FAILURE);
}

/* Creo il socket */
SOCKET sock;
SOCKET newSock;
printf("\nCreazione socket in corso...");
sock=socket(AF_INET, SOCK_STREAM, 0);

/* Stabilisco l'indirizzo IP del server secondo argomento da linea di comando, il protocollo utilizzato e il port number (terzo argomento da linea di comando*/
memset(&target, 0, sizeof(target));
target.sin_family = AF_INET;
target.sin_addr.s_addr = htonl(INADDR_ANY);// l'argomento di htons deve essere un intero, uso atoi che converte da stringa a intero;
target.sin_port =htons(port);//argv[2] è la porta; htons converte il numero di porta voluto, perchè i valori utilizzati
//da internet sono diversi da quelli del pc.

/* Effettuo il bind */

printf("\nBind in corso...");
if(bind(sock,(struct sockaddr *)&target, sizeof(target))==SOCKET_ERROR){
printf("Errore nel bind");
}

/* Mi metto in ascolto */

if(listen(sock,LISTENQ) ==SOCKET_ERROR) { // listenq sono il numero di connessioni sospese
printf("server: Errore durante la listen");
exit(EXIT_FAILURE);
}

/* Creo un nuovo socket per la connessione del singolo client */

while(1) {
printf("\nSono in attesa di una connessione...\n");
if((newSock = accept(sock, (struct sockaddr *) &accepted, &acceptedLen))==INVALID_SOCKET){ // accept = attesa di connessione
printf("\nErrore: Impossibile creare un nuovo socket!\nConnessione fallita\n");
}

/* Primo contatto con il client */

printf("Server: connessione da %s:%d\n", inet_ntoa(accepted.sin_addr),accepted.sin_port);
while (send(newSock,"OK",strlen("OK"),0)==SOCKET_ERROR) {
printf("Errore durante la system call");
}
printf("\nConnessione avvenuta");
printf("\nIn attesa del login...");

/* Effettuo il login del client */

int permessi;
permessi = login(newSock);
if(permessi != -1){

/* In caso di Login invoco la funzione che gestisce le richieste del client */

servizio(permessi, newSock);
}
/* Il client si è disconnesso */

printf("\nConnessione terminata.\n");


/* Close the connected socket */

if ( closesocket(newSock) == SOCKET_ERROR )
{
fprintf(stderr, "server: errore durante la close.\n");
exit(EXIT_FAILURE);
}

}
if ( closesocket(sock) == SOCKET_ERROR )
{
fprintf(stderr, "server: errore durante la close.\n");
exit(EXIT_FAILURE);
}
WSACleanup();

}

int ParseCmdLine(int argc, char *argv[], char **szPort)
{
int n = 1;

while ( n < argc )
{
if ( !strncmp(argv[n], "-p", 2) || !strncmp(argv[n], "-P", 2) )
*szPort = argv[++n];
else
if ( !strncmp(argv[n], "-h", 2) || !strncmp(argv[n], "-H", 2) )// il -h è l'help
{
printf("Sintassi:\n\n");
printf(" server -p (porta) [-h]\n\n");
exit(EXIT_SUCCESS);
}
++n;
}
if (argc==1)
{
printf("Sintassi:\n\n");
printf(" server -p (porta) [-h]\n\n");
exit(EXIT_SUCCESS);
}
return 0;
}

lorenzo001
14-03-2013, 23:17
E quindi è come ti dicevo io ... dato che hai una funzione

void startServer(int argc, char**argv)

devi chiamarla con

if(opzione==2) startServer(argc, argv);

Cosa non va?

pocho183
14-03-2013, 23:21
facendo come mi dici mi da questo errore:

error C2660: 'startServer': la funzione non accetta 2 argomenti

IntelliSense: l'argomento di tipo "int" è incompatibile con il parametro di tipo "char **"

IntelliSense: troppi argomenti nella chiamata di funzione

lorenzo001
14-03-2013, 23:22
Scusa, ma quali file ci sono in questo tuo progetto?

Hai presentato due file che si chiamano Server.c ... come è questa storia?

E cosa c'è nel file "startServer.h" ?

pocho183
14-03-2013, 23:26
dentro file di intestazioni ci sono:
funzioniserver.h
macro.h
manutenzione.h
server.h
startserver.h

dentro file di risorse :
funzioniserver.cpp
manutenzione.cpp
server.cpp
startserver.cpp

pocho183
14-03-2013, 23:28
dentro startserver.h c'è :
/* Avvia il server */

void startServer(char** argv);

lorenzo001
14-03-2013, 23:28
E questo è sbagliato.

Nel .h e nel .cpp le funzioni devono avere lo stesso tipo e numero di argomenti. Invece sono diverse.

pocho183
14-03-2013, 23:31
Ho risolto, l'errore stava dentro startserver.h, mi ero dimenticato che esisteva. Grazie

dentro startserver c'è :

/* Avvia il server */

void startServer(int argc,char** argv);

lorenzo001
14-03-2013, 23:34
mi ero dimenticato che esisteva.

No comment ...

Grazie

Prego