0

Linux で VRPN クライアントを構築しました。これに基づいています: http://www.vrgeeks.org/vrpn/tutorial---use-vrpn

コードの一部を次に示します。

vrpn_Analog_Remote * analog = NULL;
vrpn_Button_Remote * button = NULL;
vrpn_Tracker_Remote * tracker = NULL;

// Things happen...

analog = new vrpn_Analog_Remote("pathToAnalog");
analog->register_change_handler(NULL, handleAnalog);
button = new vrpn_Button_Remote("pathToButton");
button->register_change_handler(NULL, handleButton);
tracker = new vrpn_Tracker_Remote("pathToTracker");
tracker->register_change_handler(NULL, handleTracker);

このコードで参照されているコールバックは次のとおりです。

void handleAnalog(void * userData, const vrpn_ANALOGCB a) {
  // Do stuff...
}
void handleButton(void * userData, const vrpn_BUTTONCB b) {
  // Do stuff...
}
void handleTracker(void * userData, const vrpn_TRACKERCB t) {
  // Do stuff...
}

VRPN へのこれらすべての参照が定義されている場所は次のとおりです。

https://github.com/vrpn/vrpn/blob/master/vrpn_Analog.h#L168 https://github.com/vrpn/vrpn/blob/master/vrpn_Button.h#L225 https://github.com/ vrpn/vrpn/blob/master/vrpn_Tracker.h#L284

これらは Linux で警告なしにコンパイルされ、実際に使用できます。すべてが期待どおりに機能しました。ここにあるすべての型は、コンパイラー g++ を満たしているようです。

しかし、Windows では、Visual Studio 2015 を使用するか MinGW の g++ を使用するかに関係なく、最初の 2 つのコールバック登録で次のようになります。

invalid conversion from 'void (*)(void*, vrpn_ANALOGCB) {aka void (*)(void*, _vrpn_ANALOGCB)}' to 'vrpn_ANALOGCHANGEHANDLER {aka 
 void (__attribute__((__stdcall__)) *)(void*, _vrpn_ANALOGCB)}' [-fpermissive]

invalid conversion from 'void (*)(void*, vrpn_BUTTONCB) {aka void (*)(void*, _vrpn_BUTTONCB)}' to 'vrpn_BUTTONCHANGEHANDLER {aka 
 void (__attribute__((__stdcall__)) *)(void*, _vrpn_BUTTONCB)}' [-fpermissive]

そして最後のものについては、別のエラーが発生します。

call of overloaded 'register_change_handler(NULL, void (&)(void*, vrpn_TRACKERCB))' is 
 ambiguous

これを入力しているので、VRPN が Windows で別の方法でコンパイルされたのではないかと考えています。そのため、コンパイラでコードに問題が発生しています。しかし、私は何をすべきかについて非常に迷っています。

4

1 に答える 1

2

次のようにコールバックを宣言してみてください。

void VRPN_CALLBACK handleAnalog(void * userData, const vrpn_ANALOGCB a) {
  // Do stuff...
}

Linux の場合、VRPN_CALLBACK定義は空であるため、そこに問題はありませんでした。Windows の場合、VRPN ライブラリの開発者は、__stdcall呼び出し規約に準拠したコールバックを想定していると判断しました。したがって、それに応じて関数を宣言する必要があります。最も簡単で移植性の高い方法はVRPN_CALLBACK、それらが提供するものとまったく同じ定義を使用することです。

これの手がかりは、github のコードへのリンクから得られました。

[vrpn_Analog.h]
typedef void(VRPN_CALLBACK *vrpn_ANALOGCHANGEHANDLER)(void *userdata,
                                                      const vrpn_ANALOGCB info);

コールバックの定義はここで行われます。

[vrpn_Configure.h]
#ifdef _WIN32   // [ ...
#define VRPN_CALLBACK __stdcall
#else // ... ] WIN32 [
#define VRPN_CALLBACK
#endif // ] not WIN32
于 2016-01-29T19:26:12.287 に答える