0

私はまだc ++に慣れていません。複数のソースからのメッセージを読みたい。各ソースは、4 文字の ID でデータ メッセージを開始します。また、それぞれに複数のデータ メッセージがあります。デバイスから必要なすべての情報が 1 つのメッセージに含まれているわけではありません。ID をオブジェクト名としてオブジェクトを作成した場合、次にメッセージを受信したときに、オブジェクトは更新されるか、完全に再構築されますか? コードでオブジェクトを呼び出す前に、オブジェクトが既に構築されているかどうかを確認する方法はありますか?

  class Channels{
public:
    INT8U systemID;    //0x01 Glonass, 0x02 GPS
    INT8U satID;
    INT8U GlonassNumber;
    INT8U SNR;         //signal to noise ratio
    FP64 carrierPhase; //cylces
    FP64 psuedoRange;  //milliseconds
    FP64 doppler;      //HZ cycles
    float tropDelay; //meters
    float ionoDelay; //meters
};
class BaseStation{
public:
    Channels channel[32];   //each channel object has all channel class variables in it
    int numberSatelitesTracked;
    FP64 timeUTC;
    INT16U week;
    FP64 GPStoUTCoffset;
    FP64 GLOtoUTCoffset;
    INT8S recieverTimeOffset;
    FP64 posX;   //geocentric coordinates in meters
    FP64 posY;
    FP64 posZ;
    FP64 rmsX;   //expected root mean square error of coordinates
    FP64 rmsY;
    FP64 rmsZ;
};
 if( check == SOCKET_ERROR){
            if( WSAGetLastError() != WSAEWOULDBLOCK){
                printf("base station client recieve failed with error %d \n",         WSAGetLastError());
                FreeSocketInformation(i); //shuts down client socket if no data
            }
            continue;
        }
        else{
            //recieve bytes into array
            memcpy(recvArray, SocketInfo->DataBuf.buf, SocketInfo->RecvBytes +1);
            //print recieved bytes on screen
            printf("%s \n", SocketInfo->DataBuf.buf);

        //first 4 bytes in message are base ID
            cBuffer[0] = recvArray[0];
            cBuffer[1] = recvArray[1];
            cBuffer[2] = recvArray[2];
            cBuffer[3] = recvArray[3];
            baseID = cBuffer;
        //create object with 4 char name
            BaseStation baseID;

        //test message identity and sort data
            if(recvArray[4] == 0x10 && recvArray[5] == 0xF5){
                baseID.timeUTC = combine64(recvArray[6]);
                baseID.week = combine16u(recvArray[14]);
                baseID.GPStoUTCoffset = combine64(recvArray[16]);
                baseID.GLOtoUTCoffset = combine64(recvArray[24]);
                baseID.recieverTimeOffset = recvArray[32];
                int noChannels = (check-30) /30 ;
                if (noChannels >= 32){
                    noChannels = 32;
                }
                int x = 33;
                for(int m = 0; m < noChannels; m++){   //advance reading for channel m

                    baseID.channel[m].systemID = recvArray[x];
                    x++;
                    baseID.channel[m].satID = recvArray[x];
                    x++;
                    baseID.channel[m].GlonassNumber = recvArray[x];
                    x++;
                    baseID.channel[m].SNR = recvArray[x];
                    x++;
                    baseID.channel[m].carrierPhase = combine64(recvArray[x]);
                    x = x+8;
                    baseID.channel[m].psuedoRange = combine64(recvArray[x]);
                    x = x+8;
                    baseID.channel[m].doppler = combine64(recvArray[x]);
                    x = x+10;
                }  //end of for loop to gather F5 sat data
            }  //end F5 message data


            if(recvArray[4] == 0x10 && recvArray[5] == 0xF6){
                baseID.posX = combine64(recvArray[6]);
                baseID.posY = combine64(recvArray[14]);
                baseID.posZ = combine64(recvArray[22]);
                baseID.rmsX = combine64(recvArray[30]);
                baseID.rmsY = combine64(recvArray[38]);
                baseID.rmsZ = combine64(recvArray[46]);
            } //end F6 message data

わかりましたので、配列が使用するのに最適なようです。では、100 個の基本オブジェクトをセットアップしてから、アクティブな配列要素を 2 番目のブール配列で追跡すると、うまくいくように見えますか? (基本オブジェクトに追加された baseID)

BaseStation base[100];
boolean baseActive[100];
int baseNumber;
//begin message processing------------------------------------------------------------
        //first 4 bytes in message are base ID
            cBuffer[0] = recvArray[0];
            cBuffer[1] = recvArray[1];
            cBuffer[2] = recvArray[2];
            cBuffer[3] = recvArray[3];
            string name = cBuffer;
//check for existing baseID------------------------------------------------------------
// 100 array positions
//find if base is already in use, create new if not in use
        for(baseNumber = 0; base[baseNumber].baseID != name; baseNumber++){
            //for statement increases untill it finds baseID == name
            if( baseNumber >= 100){ //baseID not currently in use
                for(int n=0; baseActive[n] == true; n++){
                    //for statement increases untill finds a false baseActive
                    baseNumber = n; //assign baseNumber to the array position
                    base[baseNumber].baseID = name; //create new baseID
                    continue;
                }
            }
        }
//check and process message data--------------------------------------------------------
        if( base[baseNumber].baseID == name){
            baseActive[baseNumber] = true;
            //test message identity and sort data
           }//end of for loop

//test connection, if no bytes recieved then connection is closed.----------------------
            if( SocketInfo->RecvBytes == 0){
                FreeSocketInformation(i); //shuts down client socket if no data
                continue;
            }
        }
    } //end of read data from socket
}

//need to add a timer to remove non sending bases from the baseActive[] array
4

2 に答える 2

3

C++ は静的に型付けされた言語です。コンパイル時にオブジェクト名を指定する必要があります。
実行時にオブジェクト名を作成して、その名前でオブジェクトを作成することはできません。

于 2012-12-20T04:24:56.907 に答える
1

すでに回答されているように、C++ ではできません。ただし、他の方法で問題を解決できます。最初に、ID を BaseStation 構造の具体的なオブジェクトにバインドする必要があります。このリンクは 2 つの方法で提供できます。キーが ID である連想コンテナーに BaseStation オブジェクトを保持する方法と、BaseStation オブジェクトの配列を保持する方法です (私が推測できる限り、何らかのマイクロコントローラー コードを作成しているため、std コンテナーは使用できません)。ご利用いただけます)。

最初のアプローチのコード例:

//id is 4 char so it can be thought as int on most systems
std::map<int, BaseStation *> baseStations;
int * id = (int*)recvArray; //this hack is for showing how you can convert 4 char to int
    //may be in your code (int id = combine32(recvArray[0])) is equvivalent
if(baseStations.find(*id) != baseStations.end()) //checking existance of object with such id
{
    //ok, exists, do nothing
}
else
    baseStations[*id] = new BaseStation(); //create new

baseStations[*id].timeUTC = combine64(recvArray[6]); //starting copying values
//other values copying

2 番目の状況では、連想コンテナーを使用できない場合、またはマイクロコントローラーのメモリ不足のために libs\code を購入できない場合は、配列のみを使用できますが、柔軟性がまったくなく、より多くの操作を消費します。例:

//BaseConnection also holds field names id;
BaseConnection baseConnections[N];
int FindId(int id); //return index of element in baseConnections array with this id

BaseConnection * workingConnection = &baseConnections[FindId(combine32(recvArray[0]))];
workingConnection->timeUTC = combine64(recvArray[6]); //starting copying values
//other values copying
于 2012-12-20T04:33:21.640 に答える