std::function にメソッドを関連付ける時は std::bind を使用しますが C++/CLI でマネージドメソッドを std::bind 渡したい場合の実装方法の紹介です。
C++11 以降で関数ポインタの代わりに std::function でコールバック呼び出しされるような局面でマネージクラスのメソッドを std::function に渡してネイティブ側から呼び出してもらいたいケースがあると思いますが std::bind にマネージドメソッドを指定すると以下のようにエラーが発生してしまいます。
// ネイティブ側の定義 class Native { public: void foo(std::function<void(int)> func) // コールバックがstd::functionなネイティブメソッド { func(999); }; } // マネージド側の定義 public ref class Managed { public: Managed(Native* lib) { auto func_1 = std::bind(this->WhatBind, gcroot<Managed^>(this), std::placeholders::_1); // この式は指定不可能 // E2071 pointer-to-member は マネージド クラスでは無効です auto func_2 = []() { this->Callback(); }; // マネージドなのでラムダも無理 // E2093 マネージド クラスのメンバー関数ではローカルラムダは使用できません lib->foo(func_1) // ★★★渡せない } void WhatBind(int arg1) { /* ... */ } }
言語仕様的に上無理なので マネージドメソッドは std::bind できません。そこで以下のようにフリー関数を1層経由させます。こうすることで制限を回避できます。
// ネイティブ側の定義 class Native { public: void foo(std::function func); // コールバックがstd::function } // マネージド側の定義 public ref class Managed { public: Managed(Native* lib); void WhatBind() { /* ... */ } } // 迂回用のネイティブ関数の定義 static void Proxy(Managed^ managed, int arg1) { managed->WhatBind(arg1); // マネージドメソッドの呼び出し } Managed::Managed(Native* lib) { // ★★★これならbindを作成できる auto func = std::bind(Proxy, gcroot<Managed^>(this), std::placeholders::_1); lib->foo(func); }
以上です。
参考
How to use boost::bind in C++/CLI to bind a member of a managed class