PDA

Visualizza la versione completa : [C++]Passare parametri tra due file .cc


ricardinho88
10-10-2012, 09:53
Salve, sto facendo una implementazione di un protocollo di routing usando il programma omnet++ che lavora in c++; il mio problema è: come posso passare il valore di una o più variabili definite in un file .cc ad un altro file .cc?
Grazie mille, aspetto un vostro aiuto.
Buona giornata!

c0der
10-10-2012, 10:19
Non so quale sia la tua conoscenza del C++ e non vorrei dirti cose normali o troppo scontate,
ma puoi ovviamente avere variabili costanti definite in un file .h comune, anche dei #define,
oppure chiamare metodi setter/getter tra i due moduli (che magari agiscono su variabili statiche al modulo,
ossia che hanno visibilità solo in quel file), oppure se modulo a chiama una funzione di modulo b gli passa
direttamente quei valori come parametri della funzione.

Ci sono tanti modi, se spieghi meglio cosa vuoi fare si cerca quello migliore, oppure
il tuo problema è più complesso e non ho capito.

ricardinho88
10-10-2012, 10:26
Grazie per avermi risposto...io ho due file .cc che riguardano un nodo che si muove nella rete; in un file .cc vengono definite due variabili (pos.x e pos.y) che assumono ogni 100 ms dei valori diversi; questi valori io vorrei passarli ad un altro file .cc che si occupa della gestione dei messaggi. Le variabili sono le posizioni del nodo sull'asse x e sull'asse y e vorrei trasmettere questi due valori al file .cc che si occupa dell'inoltro dei messaggi (ad esempio se pos.x < 30 allora cancella il messaggio oppure invialo etc). Mi sono spiegato meglio ora? Questi valori di pos.x e pos.y continuano a variare nel tempo...e io ogni volta vorrei che fossero lette dall'altro file .cc.
Spero di essermi spiegato meglio...

c0der
10-10-2012, 10:31
Si però ci sara una sincronizzazione tra i 2 moduli, a meno che siano 2 thread, cosa a cui non hai accennato.

Se NON sono 2 thread e l'esecuzione mettiamo si trova nel modulo 1 nella funzione modulo1_calcola non puoi fare così?



void modulo1_calcola()
{
... fine elaborazioni varie ...

if (pos.x < 30)
modulo2_invia(pos);
}


Se invece modulo1 e modulo2 sono 2 thread è diverso ma dovresti specificarlo.

ricardinho88
10-10-2012, 10:42
Perdonami l'ignoranza cOder ma cosa intendi per thread? Praticamente sono due file .cc diversi dove in uno si calcolano i valori di due parametri pos.x e pos.y ; i file sono indipendenti, vorrei creare io questa dipendenza tra i due file. Inoltre il calcolo del pos.x<30 vorrei farlo nell'altro file, ovvero io vorrei inviare la variabile a prescindere.
Per intenderci, nel file LinearMobility.cc calcolo in una funzione il valore di pos.x e pos.y e dopo vorrei passare questi valori al file PingApp.cc.
Se vuoi posso inviarti i due file così magari capisci meglio, dimmi tu. Oppure pubblico qui il contenuto.

c0der
10-10-2012, 10:54
Ok, riguardo ai thread puoi cominciare a dare una lettura qui: http://it.wikipedia.org/wiki/Thread_%28informatica%29

Quando esegui un programma, anche composto da più files sorgente, il processore inizia a eseguire le istruzioni dalla main(), posta mettiamo in LinearMobility.cc ed esegue le istruzioni nell'ordine che tu hai predisposto, non ne esegue un po' in LinearMobility.cc e un po' in PingApp.cc.

Se vuoi avere questo comportamento bisogna che crei 1 thread a cui assegnare 1 funzione (contenente un loop "infinito") di PingApp.cc, di modo che questa funzione "monitori" i valori che ti interessano e li spedisca all'occorrenza.

Visto che non eri a conoscenza dei thread, mi chiedo solo, se proprio non ne puoi fare a meno, visto che magari
non avendoli mai usati faticheresti un pochettino, e non ti basta controllare i valori "ogni tanto" in LinearMobility.cc e
chiamare una funzione di PingApp.cc che te li spedisce.

ricardinho88
10-10-2012, 11:01
Si si, l'ultima opzione andrebbe benissimo, ovvero una funzione che me li faccia "spedire" e li "memorizzi" dunque in PingApp.cc per poi valutarli; la richiesta era ben questa (lo so, mi esprimo male), il più è: come faccio a farli comunicare questi due file?
La cosa che ho fatto fino ad ora è stata includere LinearMobility.h in pingApp.cc ma altro non ho fatto.

c0der
10-10-2012, 11:08
L'ultima opzione è quella che ti avevo enunciato già nella prima risposta ossia "ogni tanto" in alcuni punti a tua scelta
in LinearMobility.cc scrivi:


if (pos.x < 30)
PingApp_invia(pos);

passando la posizione come argomento della funzione. Se non usi i thread non avrebbe senso che condividi pos in altra maniera.

Il tuo processore sta eseguendo 1 istruzione alla volta in LinearMobility.cc e quindi sei tu a decidere quando controllare e inviare pos. Non ci sono alternative. L'unica altra alternativa e usare i thread (nel qual caso dovresti sicuramente usare anche i mutex, vedi http://it.wikipedia.org/wiki/Mutex)

ricardinho88
10-10-2012, 11:13
Ok, grazie mille per la dritta, il più è: scrivendo così, perchè dovrebbe inviarmela al file pingApp.cc? Come fa a saperlo?
Il codice di LinearMobility.cc è:

#include "LinearMobility.h"
#include "FWMath.h"


Define_Module(LinearMobility);


void LinearMobility::initialize(int stage)
{
BasicMobility::initialize(stage);

EV << "initializing LinearMobility stage " << stage << endl;

if (stage == 0)
{
updateInterval = par("updateInterval");
speed = par("speed");
angle = par("angle");
acceleration = par("acceleration");
angle = fmod(angle,360);

// if the initial speed is lower than 0, the node is stationary
stationary = (speed == 0);

// host moves the first time after some random delay to avoid synchronized movements
if (!stationary)
scheduleAt(simTime() + uniform(0, updateInterval), new cMessage("move"));
}
}


/**
* The only self message possible is to indicate a new movement. If
* host is stationary this function is never called.
*/
void LinearMobility::handleSelfMsg(cMessage * msg)
{
move();
updatePosition();
if (!stationary)
scheduleAt(simTime() + updateInterval, msg);
}

/**
* Move the host if the destination is not reached yet. Otherwise
* calculate a new random position
*/
void LinearMobility::move()
{
pos.x += speed * cos(PI * angle / 180) * updateInterval;
pos.y += speed * sin(PI * angle / 180) * updateInterval;

// do something if we reach the wall
Coord dummy;
handleIfOutside(REFLECT, dummy, dummy, angle);

// accelerate
speed += acceleration * updateInterval;
if (speed <= 0)
{
speed = 0;
stationary = true;
}

EV << " xpos= " << pos.x << " ypos=" << pos.y << " speed=" << speed << endl;
}


Mentre il codice di PingApp.cc è:

#include <limits.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <sstream>
#include <string>


#include "IPAddressResolver.h"
#include "PingApp.h"
#include "PingPayload_m.h"
#include "IPControlInfo.h"
#include "IPv6ControlInfo.h"
#include "IP.h"
#include "FlatNetworkConfigurator.h"
#include "BasicMobility.h"
#include "LinearMobility.h"

using std::cout;
using std::string;


Define_Module(PingApp);

void PingApp::initialize()
{
// read params
// (defer reading srcAddr/destAddr to when ping starts, maybe
// addresses will be assigned later by some protocol)

packetSize = par("packetSize");
intervalp = & par("interval");
hopLimit = par("hopLimit");
count = par("count");
startTime = par("startTime");
stopTime = par("stopTime");
printPing = (bool)par("printPing");
numHosts = par("numHosts");
int i;
string lista[numHosts];
string a;




// state
sendSeqNo = expectedReplySeqNo = 0;
WATCH(sendSeqNo);
WATCH(expectedReplySeqNo);

// statistics
delayStat.setName("pingRTT");
delayVector.setName("pingRTT");
dropVector.setName("pingDrop");

dropCount = outOfOrderArrivalCount = numPongs = 0;
WATCH(dropCount);
WATCH(outOfOrderArrivalCount);
WATCH(numPongs);


for (i=1;i<numHosts;i++)
{
std::string s;
std::stringstream out;
out << i;
s = out.str();
string ip="192.168.0."+s;
lista[i]=ip;
}

EV << "Questi sono gli indirizzi IP: \n";

for (i=1;i<numHosts+1;i++)
{
EV <<"Nodo" <<(i-1)<< ": " <<lista[i] << "\n";

}



// schedule first ping (use empty destAddr or stopTime<=startTime to disable)
if (par("destAddr").stringValue()[0] && (stopTime==0 || stopTime>=startTime))
{
cMessage *msg = new cMessage("sendPing");
scheduleAt(startTime, msg);
}
}

void PingApp::handleMessage(cMessage *msg)
{

if (msg->isSelfMessage())
{
// on first call we need to initialize
if (destAddr.isUnspecified())
{
destAddr = IPAddressResolver().resolve(par("destAddr"));
ASSERT(!destAddr.isUnspecified());
srcAddr = IPAddressResolver().resolve(par("srcAddr"));
EV << "Starting up: dest=" << destAddr << " src=" << srcAddr << "\n";
}
EV << "Il numero di hosts è: "<< numHosts << " \n";
contatore++;
EV<< "Ho ricevuto esattamente " << contatore << " ping \n";
// send a ping
sendPing();

// then schedule next one if needed
scheduleNextPing(msg);
}
else
{
// process ping response
processPingResponse(check_and_cast<PingPayload *>(msg));
}
}

void PingApp::sendPing()
{
EV << "Sending ping #" << sendSeqNo << "\n";

char name[32];
sprintf(name,"ping%ld", sendSeqNo);

PingPayload *msg = new PingPayload(name);
msg->setOriginatorId(getId());
msg->setSeqNo(sendSeqNo);
msg->setByteLength(packetSize);

sendToICMP(msg, destAddr, srcAddr, hopLimit);
}

void PingApp::scheduleNextPing(cMessage *timer)
{
simtime_t nextPing = simTime() + intervalp->doubleValue();
sendSeqNo++;
if ((count==0 || sendSeqNo<count) && (stopTime==0 || nextPing<stopTime))
scheduleAt(nextPing, timer);
else
delete timer;
}

void PingApp::sendToICMP(cMessage *msg, const IPvXAddress& destAddr, const IPvXAddress& srcAddr, int hopLimit)
{
if (!destAddr.isIPv6())
{
// send to IPv4
IPControlInfo *ctrl = new IPControlInfo();
ctrl->setSrcAddr(srcAddr.get4());
ctrl->setDestAddr(destAddr.get4());
ctrl->setTimeToLive(hopLimit);
msg->setControlInfo(ctrl);
send(msg, "pingOut");
}
else
{
// send to IPv6
IPv6ControlInfo *ctrl = new IPv6ControlInfo();
ctrl->setSrcAddr(srcAddr.get6());
ctrl->setDestAddr(destAddr.get6());
ctrl->setHopLimit(hopLimit);
msg->setControlInfo(ctrl);
send(msg, "pingv6Out");
}
}


void PingApp::processPingResponse(PingPayload *msg)
{
// get src, hopCount etc from packet, and print them
IPvXAddress src, dest;
int msgHopCount = -1;
if (dynamic_cast<IPControlInfo *>(msg->getControlInfo())!=NULL)
{
IPControlInfo *ctrl = (IPControlInfo *)msg->getControlInfo();
src = ctrl->getSrcAddr();
dest = ctrl->getDestAddr();
msgHopCount = ctrl->getTimeToLive();
}
else if (dynamic_cast<IPv6ControlInfo *>(msg->getControlInfo())!=NULL)
{
IPv6ControlInfo *ctrl = (IPv6ControlInfo *)msg->getControlInfo();
src = ctrl->getSrcAddr();
dest = ctrl->getDestAddr();
msgHopCount = ctrl->getHopLimit();
}

simtime_t rtt = simTime() - msg->getCreationTime();

if (printPing)
{
cout << getFullPath() << ": reply of " << std::dec << msg->getByteLength()
<< " bytes from " << src
<< " icmp_seq=" << msg->getSeqNo() << " ttl=" << msgHopCount
<< " time=" << (rtt * 1000) << " msec"
<< " (" << msg->getName() << ")" << endl;
}

// update statistics
countPingResponse(msg->getByteLength(), msg->getSeqNo(), rtt);
delete msg;
}

void PingApp::countPingResponse(int bytes, long seqNo, simtime_t rtt)
{
EV << "Ping reply #" << seqNo << " arrived, rtt=" << rtt << "\n";

numPongs++;

delayStat.collect(rtt);
delayVector.record(rtt);

if (seqNo == expectedReplySeqNo)
{
// expected ping reply arrived; expect next sequence number
expectedReplySeqNo++;
}
else if (seqNo > expectedReplySeqNo)
{
EV << "Jump in seq numbers, assuming pings since #" << expectedReplySeqNo << " got lost\n";

// jump in the sequence: count pings in gap as lost
long jump = seqNo - expectedReplySeqNo;
dropCount += jump;
dropVector.record(dropCount);

// expect sequence numbers to continue from here
expectedReplySeqNo = seqNo+1;
}
else // seqNo < expectedReplySeqNo
{
// ping arrived too late: count as out of order arrival
EV << "Arrived out of order (too late)\n";
outOfOrderArrivalCount++;
}
}


void PingApp::finish()
{
if (sendSeqNo==0)
{
if (printPing)
EV << getFullPath() << ": No pings sent, skipping recording statistics and printing results.\n";
recordScalar("Pings sent", sendSeqNo);
return;
}

Come dovrei modificare il tutto affinchè PingApp.cc riceva i due valori desiderati? Grazie mille sempre!

c0der
10-10-2012, 11:20
Non è che potresti modificare il messaggio inserendo il codice tra i tag "code", altrimenti si perde l'indentazione ed un po' faticoso leggerlo. Basta che premi su "modifica" e poi tagli il codice, inserisci i tag code e dentro ci rimetti il tuo codice con gli spazi.

Ma questo programma l'hai scritto tu?

Loading