3

イベント ハンドラー関数があり、その関数にはクラスのメンバー関数への呼び出しがあります。イベント ハンドラー関数は、クラス cpp ファイルで宣言されていますが、クラスの一部ではなく、メンバー関数ではありません。

コードをコンパイルすると、グローバル イベント ハンドラー関数内でメンバー関数を呼び出しているため、関数はスコープ内にあるとコンパイラーは言います。

私の質問は次のとおりです。グローバル関数でメンバー関数を使用する方法はありますか? (オブジェクトは実行時に最初に作成されます)。

以下は、メンバー関数とグローバル イベント ハンドラーです。

Global event handler:

void adbEventHandler(Connection * connection, adb_eventType event, uint16_t length, uint8_t *     data)
{
     Serial.println("In data recieve handler");


    Serial.println("Data recieved: ");
    Serial.println(data[0]);
    Serial.println(data[1]);

    char a = data[0];
    char b = data[1];

   Serial.println(a);
   Serial.println(b);
   //uint16_t data2 = data;

   // Member function of USBCommunicator class
   SendBuffer(data, sizeof(data));

}

メンバー関数:

void CommunicationModuleUSB::SendBuffer(uint8_t * Buffer, int Size){

    connection->write(Size,(uint8_t*)&Buffer);
}

アップデート

ダニエルの返信で(ありがとう!)、次のようにヘッダーファイルとcppファイルのメンバー関数を静的に変更しました:

    static void CommunicationModuleUSB::SendBuffer(uint8_t* Buffer, int Size);

そして、関数は次のようにグローバル イベント ハンドラで呼び出されます。

// Event handler for shell connection; called whenever data sent from Android to Microcontroller
void adbEventHandler(Connection * connection, adb_eventType event, uint16_t length, uint8_t *       data)
{
   Serial.println("In data recieve handler");


   Serial.println("Data recieved: ");
   //Serial.println(*data);
   Serial.println(data[0]);
   Serial.println(data[1]);

   char a = data[0];
   char b = data[1];

   Serial.println(a);
   Serial.println(b);
   //uint16_t data2 = data;

   CommunicationModuleUSB::SendBuffer(data, sizeof(data));


 }

今だけ、コンパイル時に次のエラーが発生します。

C:\Users\Gebruiker\Documents\Arduino\libraries\CommunicationModuleUSB/CommunicationModuleUSB.h:26: エラー: メンバー 'SendBuffer の追加修飾 'CommunicationModuleUSB::'。

誰がそれを解決するのか考えている人はいますか?

更新 2

返信ありがとうございます。

あなたのフィードバックでメンバー関数を変更しました。しかし、今では次のエラーが発生します。

C:\Users\Gebruiker\Documents\Arduino\libraries\CommunicationModuleUSB\CommunicationModuleUSB.cpp:77: エラー: メンバ関数 'static void CommunicationModuleUSB::SendBuffer(uint8_t*, int)' を静的リンケージに宣言できません

ヘッダー ファイルで Connection 変数を static にしました。以下は、cpp ファイルからのヘッダー ファイルと関数定義です。

あなた(または他の誰か)は手がかりを持っていますか?すべての提案を歓迎します!

ヘッダー ファイル:

#include "CommunicationModule.h"
#include <SPI.h>
#include <Adb.h>

class CommunicationModuleUSB : public CommunicationModule
{
    public:

CommunicationModuleUSB();

int Connect();
      void Send();
int CheckConnection();
      void Recieve();
static void SendBuffer(uint8_t* Buffer, int Size);

void RecieveBuffer(char Buffer[], int Size);

// Adb connection made this static....(is this right?
static Connection * connection;

// Elapsed time for sensor sampling
long lastTime;

      private:
};

cpp ファイルの関数宣言:

static void CommunicationModuleUSB::SendBuffer(uint8_t* Buffer, int Size){

    connection->write(Size,(uint8_t*)&Buffer);
}

そして、グローバル関数の呼び出し:

CommunicationModuleUSB::SendBuffer(data, sizeof(data));

アップデート 3

Daniel の助けを借りて te コードを更新しました。唯一の問題は、クラスで宣言されている Connection 変数がスコープ内にないことです。

私が得るコンパイラエラーは次のとおりです: C:\Users\Gebruiker\Documents\Arduino\libraries\CommunicationModuleUSB/CommunicationModuleUSB.cpp:79: CommunicationModuleUSB::connection へのCommunicationModuleUSB::connection' C:\Users\Gebruiker\Documents\Arduino\libraries\CommunicationModuleUSB/CommunicationModuleUSB.cpp:79: undefined reference to未定義参照CommunicationModuleUSB::Connect()': C:\Users\Gebruiker\Documents\Arduino\libraries\CommunicationModuleUSB/CommunicationModuleUSB.cpp:53: undefined reference to::connection' C:\Users\Gebruiker\Documents\Arduino\libraries\CommunicationModuleUSB/CommunicationModuleUSB.cpp:53: 「CommunicationModuleUSB::connection」への未定義の参照

接続変数は、ヘッダー ファイルで次のように宣言されます。

// Adb connection made this static....(is this right?
      static Connection * connection;

この変数は、次のメンバー関数で使用されます。

void CommunicationModuleUSB::SendBuffer(uint8_t* Buffer, int Size){

connection->write(Size,(uint8_t*)&Buffer);
}

And は、次のグローバル イベント ハンドラー関数で使用されます。

// Event handler for shell connection; called whenever data sent from Android to Microcontroller
void adbEventHandler(Connection * connection, adb_eventType event, uint16_t length, uint8_t *   data)
{
   Serial.println("In data recieve handler");


   Serial.println("Data recieved: ");
   Serial.println(data[0]);
   Serial.println(data[1]);

   char a = data[0];
   char b = data[1];

   Serial.println(a);
   Serial.println(b);

   CommunicationModuleUSB::SendBuffer(data, sizeof(data));
}

これを解決する方法を提案している人はいますか?

4

1 に答える 1

2

メンバー関数はメンバー関数であり、それには理由があります。SendBuffer()グローバルスコープで定義された通常の関数であるかのように呼び出していますが、そうではありません。メンバー関数は 2 つの方法で呼び出すことができます。

最初: クラスのインスタンスを作成してから、メソッドを呼び出します。

CommunicationModuleUSB cm();
cm.SendBuffer(data, sizeof(data));

static2番目:署名が次のようになるようにメソッドを作成します。

static void CommunicationModuleUSB::SendBuffer(uint8_t * Buffer, int Size);

したがって、宣言は次のようになります。

class CommunicationModuleUSB
{
    //Other stuff
    static void SendBuffer(uint8_t * Buffer, int Size);
    //Other stuff
}

および関数の定義:

void CommunicationModuleUSB::SendBuffer(uint8_t * Buffer, int Size)
{
    //Your code
}

これで、次のように呼び出すことができます。

CommunicationModuleUSB::SendBuffer(data, sizeof(data));

しかし、これにはさらに多くの意味があります。メソッドを静的にすると、特定のオブジェクトに属さないため、クラスの静的メンバー変数のみにアクセスできます。ただし、特定のオブジェクトに属するメソッドを呼び出すことは、まだ存在しないeat()メソッドを呼び出すこととまったく同じであるため、これは理にかなっています。Carrot

于 2013-10-26T08:58:00.303 に答える