COMメソッドを関数の引数として渡す方法は? MicrosoftコンパイラエラーC3867
-
05-07-2019 - |
質問
COMメソッドを関数の引数として渡したいのですが、このエラーが表示されます(Microsoft(R)32-bit C / C ++ Optimizing Compiler Version 15.00.30729.01 for 80x86):
エラーC3867: 'IDispatch :: GetTypeInfoCount':関数呼び出しに引数リストがありません。 '& IDispatch :: GetTypeInfoCount'を使用して、メンバーへのポインターを作成します
不足しているものは何ですか?
ありがとうございます。
#include <atlbase.h>
void update( HRESULT(*com_uint_getter)(UINT*), UINT& u )
{
UINT tmp;
if ( S_OK == com_uint_getter( &tmp ) ) {
u = tmp;
}
}
// only for compile purpose, it will not work at runtime
int main(int, char*[])
{
// I choose IDispatch::GetTypeInfoCount just for the sake of exemplification
CComPtr< IDispatch > ptr;
UINT u;
update( ptr->GetTypeInfoCount, u );
return 0;
}
解決 3
morechilli が指摘したように、これはC ++の問題です。 同僚のダニエルのおかげで、ここに解決策があります:
#include <atlbase.h>
template < typename interface_t >
void update( interface_t* p, HRESULT (__stdcall interface_t::*com_uint_getter)(UINT*), UINT& u )
{
UINT tmp;
if ( S_OK == (p->*com_uint_getter)( &tmp ) ) {
u = tmp;
}
}
// only for compile purpose, it will not work at runtime
int main(int, char*[])
{
// I choose IDispatch::GetTypeInfoCount just for the sake of exemplification
CComPtr< IDispatch > ptr;
UINT u;
update( ptr.p, &IDispatch::GetTypeInfoCount, u );
return 0;
}
他のヒント
まっすぐなC ++の問題のように見えます。
メソッドは関数へのポインタを予期しています。
メンバー関数があります-(関数とは異なります)。
通常、次のいずれかが必要です。
1.渡す関数を静的に変更します。
2.メンバー関数ポインターに期待されるポインターのタイプを変更します。
メンバー関数ポインターを処理するための構文は最適ではありません...
標準的なトリックは(1)で、このポインタをオブジェクトに明示的に渡します 引数として、非静的メンバーを呼び出すことができます。
Boost.Functionもここでは妥当な選択です(以下に書いたものをテストしなかったため、いくつかの変更が必要になる場合があります-特に、何らかのgetを呼び出す必要があるかどうかはわかりません) ()CComPtrオブジェクトのメソッド):
#include <atlbase.h>
#include <boost/function.hpp>
#include <boost/bind.hpp>
void update( boost::function<HRESULT (UINT*)> com_uint_getter, UINT& u )
{
UINT tmp;
if ( S_OK == com_uint_getter( &tmp ) ) {
u = tmp;
}
}
// only for compile purpose, it will not work at runtime
int main(int, char*[])
{
// I choose IDispatch::GetTypeInfoCount just for the sake of exemplification
CComPtr< IDispatch > ptr;
UINT u;
update( boost::bind(&IDispatch::GetTypeInfoCount, ptr), u );
return 0;
}
これは、morechilliが言及したすべてのメンバーへのポインターと同じですが、それを使用する厄介な構文の一部を隠しています。